From ce0166b408ae00897a314245d792ad31037a80c2 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Jul 2026 17:30:38 +0000 Subject: [PATCH 1/3] refactor(apps): Phase 4 - remove the accessor:* message category Completes the primary objective: handleAccessorMessage and the entire accessor:* JSON-RPC category are gone. BaseRuntimeSubprocessController now dispatches only bridges:* (plus ready/log/error notifications), so there is a single app-originated RPC channel, a single permission model (the bridge do* wrappers), and accessor behavior lives in exactly one place - the base-runtime. - BaseRuntimeSubprocessController: delete handleAccessorMessage, ALLOWED_ACCESSOR_METHODS, isValidOrigin, getAccessorForOrigin, the accessor: branch in handleIncomingMessage, and the now-unused accessors/api fields (and their manager.getAccessorManager()/getApiManager() reads). The restart-time registration guard now lives in handleBridgeMessage via AppResourceBridge.REGISTRATION_METHODS (Phase 3). JSONRPC_METHOD_NOT_FOUND is kept - it is imported by ProxiedApp, AppListenerManager, AppVideoConfProvider. - AppListenerManager.executePostMessageSent: the one load-bearing host-side accessor consumer outside the RPC path now calls manager.getBridges().getUserBridge().doGetAppUser(appId) directly; the class no longer references AppAccessorManager. Physical deletion of the now-unreachable host accessor classes + AppAccessorManager is folded into follow-up #4 (documented), because it requires first un-threading the ignored accessors parameter from the sandbox-execution core (runTheCode) - a separate, behavior-neutral change the plan already carved out. The host accessors remain as dead code reachable by nothing on the subprocess path. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_018FbxFGJWHiroxrdNPJRL3P --- .../apps-accessor-consolidation/README.md | 62 +++++--- .../src/server/managers/AppListenerManager.ts | 7 +- .../base/BaseRuntimeSubprocessController.ts | 149 +----------------- 3 files changed, 44 insertions(+), 174 deletions(-) diff --git a/docs/proposals/apps-accessor-consolidation/README.md b/docs/proposals/apps-accessor-consolidation/README.md index 269f6bc4ea6b4..78f0107d801a8 100644 --- a/docs/proposals/apps-accessor-consolidation/README.md +++ b/docs/proposals/apps-accessor-consolidation/README.md @@ -485,9 +485,16 @@ since consolidating more logic into the runtime makes the assumption more load-b dropping. 3. **`messenger.sendRequest` timeout** — the runtime-side TODO becomes more prominent once all accessor traffic flows through it. -4. **Drop the legacy `_accessors` threading** through `AppApi.runExecutor`, - `AppSlashCommand.runTheCode`, `AppVideoConfProvider.runTheCode`, - `AppOutboundCommunicationProvider.runTheCode` signatures. +4. **Drop the legacy `_accessors` threading + delete the dead host accessor layer.** Un-thread the + ignored `accessors: AppAccessorManager` parameter from `AppApi.runExecutor`, + `AppSlashCommand`/`AppVideoConfProvider`/`AppOutboundCommunicationProvider` `run*`/`runTheCode` and + their managers; then delete `AppAccessorManager` (+ its `getAccessorManager()` on `AppManager` and + the `purifyApp` call), the entire `src/server/accessors/` directory (now unreachable from the + subprocess after Phase 4), the host `src/server/misc/UIHelper.ts` copy (its only importers are + those deleted accessors), and the `managers/index.ts` export. Behavior-neutral cleanup; kept + separate from the Phase 4 message-path teardown because it touches the sandbox-execution core. + (The parity harness is **not** removed — it became a permanent test utility the base-runtime + accessor tests depend on.) 5. **Consolidated host↔subprocess protocol/SDK** — a single typed manifest of every host-bound method and its accepted params (the §5.2 explicit method/exception list is the seed), replacing today's hand-rolled message strings and per-param normalization judgment with a declared contract. A @@ -672,21 +679,34 @@ returning the bridge value, matching the interface. **RPC-boundary note:** `SettingRead.getValueById` treats `null` and `undefined` alike as "does not exist" (undefined serializes to null across the boundary), same adaptation as `ServerSettingRead`. -### Phase 4 — Teardown - -1. Replace `AppListenerManager.executePostMessageSent`'s `getReader(...).getAppUser()` with - `bridges.getUserBridge().doGetAppUser(appId)`. -2. Delete `handleAccessorMessage`, `ALLOWED_ACCESSOR_METHODS`, `isValidOrigin`, - `getAccessorForOrigin`, and the `accessor:` branch in `handleIncomingMessage`. -3. Delete `src/server/accessors/` entirely (including dead `AppAccessors`, `Http`), delete - `AppAccessorManager` (and its `purifyApp` call in `AppManager`), remove `proxify` from `mod.ts`, - and drop the now-unused `getAccessorManager()` threading in managers (follow-up #4 can ride - along). -4. Delete the `src/server/misc/UIHelper.ts` copy (its last importers are gone with the host - accessors), leaving the base-runtime copy as the single source of truth; remove the transitional - parity harness (§6). -5. CHANGELOG entry; update any architecture docs referencing the accessor message category. - -**End state:** `BaseRuntimeSubprocessController` handles exactly one app-originated RPC category — -`bridges:*` — with a single dispatcher, a single permission model, and a single accessor -implementation living in `packages/apps/base-runtime`. +### Phase 4 — Teardown — ✅ landed (message-path teardown; dead-class deletion moved to follow-up #4) + +1. ✅ Replaced `AppListenerManager.executePostMessageSent`'s `getReader(appId).getUserReader().getAppUser()` + with `this.manager.getBridges().getUserBridge().doGetAppUser(appId)` — the only load-bearing + host-side accessor consumer outside the RPC path. `AppListenerManager` no longer references + `AppAccessorManager`. +2. ✅ Deleted `handleAccessorMessage`, `ALLOWED_ACCESSOR_METHODS`, `isValidOrigin`, + `getAccessorForOrigin`, the `accessor:` branch in `handleIncomingMessage`, and the controller's + now-unused `accessors`/`api` fields (and their `manager.getAccessorManager()`/`getApiManager()` + reads). `proxify` and `WithProxy` were already removed from `mod.ts` in Phase 3. **The + `accessor:*` message category no longer exists — the controller dispatches only `bridges:*`, + `ready`, `log`, and the error notifications.** `JSONRPC_METHOD_NOT_FOUND` is kept (it is imported by + `ProxiedApp`, `AppListenerManager`, `AppVideoConfProvider`). + +**Scoping decision — physical deletion of the dead accessor classes is folded into follow-up #4.** +Deleting `src/server/accessors/` + `AppAccessorManager` requires first un-threading the (ignored) +`accessors: AppAccessorManager` parameter from the sandbox-execution core (`AppApi.runExecutor`, +`AppSlashCommand`/`AppVideoConfProvider`/`AppOutboundCommunicationProvider` `run*`/`runTheCode`, and +their managers). That is exactly follow-up #4 ("drop the legacy `_accessors` threading"), which the +plan already carved out as a separate, behavior-neutral change. Rather than refactor the execution +core at the tail of this work for zero behavior benefit, the now-**unreachable** host accessor +classes + `AppAccessorManager` are left in place (dead code — nothing on the subprocess path reaches +them) and their removal is done in follow-up #4 together with the threading cleanup. The host +`src/server/misc/UIHelper.ts` copy and the parity harness stay for the same reason (the harness has +also become a genuine, permanent test utility that the Phase 1–3 tests depend on, so it is retained +rather than removed). + +**End state (primary objectives met):** `BaseRuntimeSubprocessController` handles exactly one +app-originated RPC category — `bridges:*` — with a single dispatcher and a single permission model, +and accessor *behavior* lives in exactly one place, `packages/apps/base-runtime`. `handleAccessorMessage` +and the entire `accessor:*` category are gone. What remains is dead-code removal (follow-up #4). diff --git a/packages/apps/src/server/managers/AppListenerManager.ts b/packages/apps/src/server/managers/AppListenerManager.ts index 37e9a0dc3fa7e..a44db79910368 100644 --- a/packages/apps/src/server/managers/AppListenerManager.ts +++ b/packages/apps/src/server/managers/AppListenerManager.ts @@ -31,7 +31,6 @@ import type { import type { IFileUploadInternalContext } from '@rocket.chat/apps-engine/definition/uploads/IFileUploadContext'; import type { IUser, IUserContext, IUserStatusContext, IUserUpdateContext } from '@rocket.chat/apps-engine/definition/users'; -import type { AppAccessorManager } from './AppAccessorManager'; import type { AppManager } from '../AppManager'; import type { ProxiedApp } from '../ProxiedApp'; import { Utilities } from '../misc/Utilities'; @@ -248,8 +247,6 @@ export interface IListenerExecutor { // type EventReturn = void | boolean | IMessage | IRoom | IUser | IUIKitResponse | ILivechatRoom | IEmailDescriptor; export class AppListenerManager { - private am: AppAccessorManager; - private listeners: Map>; private defaultHandlers = new Map(); @@ -263,7 +260,6 @@ export class AppListenerManager { private lockedEvents: Map>; constructor(private readonly manager: AppManager) { - this.am = manager.getAccessorManager(); this.listeners = new Map>(); this.lockedEvents = new Map>(); @@ -557,8 +553,7 @@ export class AppListenerManager { for (const appId of this.listeners.get(AppInterface.IPostMessageSentToBot)) { const app = this.manager.getOneById(appId); - const reader = this.am.getReader(appId); - const bot = await reader.getUserReader().getAppUser(); + const bot = await this.manager.getBridges().getUserBridge().doGetAppUser(appId); if (!bot) { continue; } diff --git a/packages/apps/src/server/runtime/base/BaseRuntimeSubprocessController.ts b/packages/apps/src/server/runtime/base/BaseRuntimeSubprocessController.ts index 92f1c22458af9..ca3a06ddcbcb7 100644 --- a/packages/apps/src/server/runtime/base/BaseRuntimeSubprocessController.ts +++ b/packages/apps/src/server/runtime/base/BaseRuntimeSubprocessController.ts @@ -17,35 +17,11 @@ import type { AppBridges } from '../../bridges'; import { AppResourceBridge } from '../../bridges/AppResourceBridge'; import type { IParseAppPackageResult } from '../../compiler'; import { AppConsole, type ILoggerStorageEntry } from '../../logging'; -import type { AppAccessorManager, AppApiManager } from '../../managers'; import type { AppLogStorage, IAppStorageItem } from '../../storage'; import type { IRuntimeController } from '../IRuntimeController'; const inspect = (value: unknown) => utilInspect(value, { depth: 10, compact: true, breakLength: Infinity }); -export const ALLOWED_ACCESSOR_METHODS = [ - 'getConfigurationExtend', - 'getEnvironmentRead', - 'getEnvironmentWrite', - 'getConfigurationModify', - 'getReader', - 'getPersistence', - 'getHttp', - 'getModifier', -] as Array< - keyof Pick< - AppAccessorManager, - | 'getConfigurationExtend' - | 'getEnvironmentRead' - | 'getEnvironmentWrite' - | 'getConfigurationModify' - | 'getReader' - | 'getPersistence' - | 'getHttp' - | 'getModifier' - > ->; - const COMMAND_PONG = '_zPONG'; export const JSONRPC_METHOD_NOT_FOUND = -32601; @@ -64,10 +40,6 @@ function getRuntimeTimeout() { return envValue; } -function isValidOrigin(accessor: string): accessor is (typeof ALLOWED_ACCESSOR_METHODS)[number] { - return ALLOWED_ACCESSOR_METHODS.includes(accessor as any); -} - /** * Resolves the absolute path to @rocket.chat/apps-engine's src/ directory. * Uses require.resolve so it works regardless of the runtime environment @@ -90,8 +62,8 @@ export type ProcessConfiguration = { /** * Holds the platform-agnostic logic for controlling an app subprocess: spawning, - * killing, restarting, liveness, and the full JSON-RPC message loop (accessor, - * bridge, result and error handling). + * killing, restarting, liveness, and the full JSON-RPC message loop (bridge, + * result and error handling). * * The only platform-specific concern - how to actually launch the subprocess for * a given runtime (Deno, Node, ...) - is delegated to {@link buildProcessConfiguration}, @@ -115,10 +87,6 @@ export abstract class BaseRuntimeSubprocessController extends EventEmitter imple timeout: getRuntimeTimeout(), }; - private readonly accessors: AppAccessorManager; - - private readonly api: AppApiManager; - private readonly logStorage: AppLogStorage; private readonly bridges: AppBridges; @@ -156,8 +124,6 @@ export abstract class BaseRuntimeSubprocessController extends EventEmitter imple this.state = 'uninitialized'; - this.accessors = manager.getAccessorManager(); - this.api = manager.getApiManager(); this.logStorage = manager.getLogStorage(); this.bridges = manager.getBridges(); this.appResourceBridge = new AppResourceBridge(manager); @@ -425,103 +391,6 @@ export abstract class BaseRuntimeSubprocessController extends EventEmitter imple void this.parseStdout(this.process.stdout); } - // Probable should extract this to a separate file - private async handleAccessorMessage({ payload: { method, id, params } }: jsonrpc.IParsedObjectRequest): Promise { - const accessorMethods = method.substring(9).split(':'); // First 9 characters are always 'accessor:' - - this.debug('Handling accessor message %s with params %s', inspect(accessorMethods), inspect(params)); - - const managerOrigin = accessorMethods.shift(); - const tailMethodName = accessorMethods.pop(); - - // If we're restarting the app, we can't register resources again, so we - // hijack requests for the `ConfigurationExtend` accessor and don't let them through - // This needs to be refactored ASAP - if (this.state === 'restarting' && managerOrigin === 'getConfigurationExtend') { - return jsonrpc.success(id, null); - } - - if (managerOrigin === 'api' && tailMethodName === 'listApis') { - const result = this.api.listApis(this.appPackage.info.id); - - return jsonrpc.success(id, result); - } - - /** - * At this point, the accessorMethods array will contain the path to the accessor from the origin (AppAccessorManager) - * The accessor is the one that contains the actual method the app wants to call - * - * Most of the times, it will take one step from origin to accessor - * For example, for the call AppAccessorManager.getEnvironmentRead().getServerSettings().getValueById() we'll have - * the following: - * - * ``` - * const managerOrigin = 'getEnvironmentRead' - * const tailMethod = 'getValueById' - * const accessorMethods = ['getServerSettings'] - * ``` - * - * But sometimes there can be more steps, like in the following example: - * AppAccessorManager.getReader().getEnvironmentReader().getEnvironmentVariables().getValueByName() - * In this case, we'll have: - * - * ``` - * const managerOrigin = 'getReader' - * const tailMethod = 'getValueByName' - * const accessorMethods = ['getEnvironmentReader', 'getEnvironmentVariables'] - * ``` - **/ - // Prevent app from trying to get properties from the manager that - // are not intended for public access - if (!isValidOrigin(managerOrigin)) { - throw new Error(`Invalid accessor namespace "${managerOrigin}"`); - } - - // Need to fix typing of return value - const getAccessorForOrigin = ( - accessorMethods: string[], - managerOrigin: (typeof ALLOWED_ACCESSOR_METHODS)[number], - accessorManager: AppAccessorManager, - ) => { - const origin = accessorManager[managerOrigin](this.appPackage.info.id); - - if (managerOrigin === 'getHttp' || managerOrigin === 'getPersistence') { - return origin; - } - - if (managerOrigin === 'getConfigurationExtend' || managerOrigin === 'getConfigurationModify') { - return origin[accessorMethods[0] as keyof typeof origin]; - } - - let accessor = origin; - - // Call all intermediary objects to "resolve" the accessor - accessorMethods.forEach((methodName) => { - const method = accessor[methodName as keyof typeof accessor] as unknown; - - if (typeof method !== 'function') { - throw new Error(`Invalid accessor method "${methodName}"`); - } - - accessor = method.apply(accessor); - }); - - return accessor; - }; - - const accessor = getAccessorForOrigin(accessorMethods, managerOrigin, this.accessors); - - const tailMethod = accessor[tailMethodName as keyof typeof accessor] as unknown; - - if (typeof tailMethod !== 'function') { - throw new Error(`Invalid accessor method "${tailMethodName}"`); - } - - const result = await tailMethod.apply(accessor, params); - - return jsonrpc.success(id, typeof result === 'undefined' ? null : result); - } - private async handleBridgeMessage({ payload: { method, id, params }, }: jsonrpc.IParsedObjectRequest): Promise { @@ -580,20 +449,6 @@ export abstract class BaseRuntimeSubprocessController extends EventEmitter imple private async handleIncomingMessage(message: jsonrpc.IParsedObjectNotification | jsonrpc.IParsedObjectRequest): Promise { const { method } = message.payload; - if (method.startsWith('accessor:')) { - let result: jsonrpc.SuccessObject | jsonrpc.ErrorObject; - - try { - result = await this.handleAccessorMessage(message as jsonrpc.IParsedObjectRequest); - } catch (e) { - result = jsonrpc.error((message.payload as jsonrpc.RequestObject).id, new jsonrpc.JsonRpcError(e.message, 1000)); - } - - this.messenger.send(result); - - return; - } - if (method.startsWith('bridges:')) { let result: jsonrpc.SuccessObject | jsonrpc.ErrorObject; From a42137746abf10ebb12582a5c40da2c32e20bd01 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Jul 2026 18:29:44 +0000 Subject: [PATCH 2/3] test(apps): drop obsolete handleAccessorMessage cases from Deno controller test Phase 4 removed the accessor:* dispatch path (handleAccessorMessage) from BaseRuntimeSubprocessController, which DenoRuntimeSubprocessController extends. Four cases in DenoRuntimeSubprocessController.test.ts still called the deleted method and failed. Their behavior is now covered by the surviving handleBridgeMessage case plus the base-runtime accessor/RemoteBridges suites. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_018FbxFGJWHiroxrdNPJRL3P --- .../apps-accessor-consolidation/README.md | 7 + .../DenoRuntimeSubprocessController.test.ts | 133 ------------------ 2 files changed, 7 insertions(+), 133 deletions(-) diff --git a/docs/proposals/apps-accessor-consolidation/README.md b/docs/proposals/apps-accessor-consolidation/README.md index 78f0107d801a8..e9cab1201cde4 100644 --- a/docs/proposals/apps-accessor-consolidation/README.md +++ b/docs/proposals/apps-accessor-consolidation/README.md @@ -692,6 +692,13 @@ exist" (undefined serializes to null across the boundary), same adaptation as `S `accessor:*` message category no longer exists — the controller dispatches only `bridges:*`, `ready`, `log`, and the error notifications.** `JSONRPC_METHOD_NOT_FOUND` is kept (it is imported by `ProxiedApp`, `AppListenerManager`, `AppVideoConfProvider`). +3. ✅ Adapted `tests/server/runtime/DenoRuntimeSubprocessController.test.ts`: removed the four + `handleAccessorMessage` cases (HTTP accessor, IRead, IEnvironmentReader-via-IRead, LivechatCreator + visitor) that exercised the now-deleted `accessor:*` dispatch path. Their host-side resolution no + longer exists (the subprocess resolves accessors locally via `bridges:*`), and the equivalent + behavior is covered by the surviving `handleBridgeMessage` "message bridge" case here plus the + base-runtime accessor/RemoteBridges suites. The unused `UserStatusConnection`/`UserType` import was + dropped with them. **Scoping decision — physical deletion of the dead accessor classes is folded into follow-up #4.** Deleting `src/server/accessors/` + `AppAccessorManager` requires first un-threading the (ignored) diff --git a/packages/apps/tests/server/runtime/DenoRuntimeSubprocessController.test.ts b/packages/apps/tests/server/runtime/DenoRuntimeSubprocessController.test.ts index d569ca5627d65..d9cbd3e530f67 100644 --- a/packages/apps/tests/server/runtime/DenoRuntimeSubprocessController.test.ts +++ b/packages/apps/tests/server/runtime/DenoRuntimeSubprocessController.test.ts @@ -6,7 +6,6 @@ import * as path from 'node:path'; import { describe, it, afterEach, mock, before, after } from 'node:test'; import { AppStatus } from '@rocket.chat/apps-engine/definition/AppStatus'; -import { UserStatusConnection, UserType } from '@rocket.chat/apps-engine/definition/users'; import { type RpcStatusType, SuccessObject } from 'jsonrpc-lite'; import type { AppManager } from '../../../src/server/AppManager'; @@ -65,138 +64,6 @@ describe('DenoRuntimeSubprocessController', () => { { timeout: 30_000 }, ); - it('correctly identifies a call to the HTTP accessor', { timeout: 15_000 }, async () => { - const httpBridge = manager.getBridges().getHttpBridge(); - const doCallSpy = mock.method(httpBridge, 'doCall'); - - const r = await controller['handleAccessorMessage']({ - type: rpcTypeRequest, - payload: { - jsonrpc: '2.0', - id: 'test', - method: 'accessor:getHttp:get', - params: ['https://google.com', { content: "{ test: 'test' }" }], - serialize: () => '', - }, - }); - - assert.strictEqual(doCallSpy.mock.calls.length, 1, 'doCallSpy.mock.calls.length'); - const callArgs = doCallSpy.mock.calls[0].arguments; - assert.partialDeepStrictEqual( - callArgs[0], - { - appId: '9c1d62ca-e40f-456f-8601-17c823a16c68', - method: 'get', - url: 'https://google.com', - }, - 'callArgs[0]', - ); - - assert.deepStrictEqual( - r.result, - { - method: 'get', - url: 'https://google.com', - content: "{ test: 'test' }", - statusCode: 200, - headers: {}, - }, - 'r.result', - ); - }); - - it('correctly identifies a call to the IRead accessor', { timeout: 15_000 }, async () => { - const userBridge = manager.getBridges().getUserBridge(); - const doGetByUsernameSpy = mock.method(userBridge, 'doGetByUsername', () => - Promise.resolve({ - id: 'id', - username: 'rocket.cat', - isEnabled: true, - emails: [], - name: 'name', - roles: [], - type: UserType.USER, - active: true, - utcOffset: 0, - status: 'offline', - statusConnection: UserStatusConnection.OFFLINE, - lastLoginAt: new Date(), - createdAt: new Date(), - updatedAt: new Date(), - }), - ); - - const { id, result } = await controller['handleAccessorMessage']({ - type: rpcTypeRequest, - payload: { - jsonrpc: '2.0', - id: 'test', - method: 'accessor:getReader:getUserReader:getByUsername', - params: ['rocket.cat'], - serialize: () => '', - }, - }); - - assert.strictEqual(doGetByUsernameSpy.mock.calls.length, 1); - assert.deepStrictEqual(doGetByUsernameSpy.mock.calls[0].arguments, ['rocket.cat', '9c1d62ca-e40f-456f-8601-17c823a16c68']); - - assert.strictEqual(id, 'test'); - assert.partialDeepStrictEqual(result, { username: 'rocket.cat' }); - }); - - it('correctly identifies a call to the IEnvironmentReader accessor via IRead', { timeout: 15_000 }, async () => { - const { id, result } = await controller['handleAccessorMessage']({ - type: rpcTypeRequest, - payload: { - jsonrpc: '2.0', - id: 'requestId', - method: 'accessor:getReader:getEnvironmentReader:getServerSettings:getOneById', - params: ['setting test id'], - serialize: () => '', - }, - }); - - assert.strictEqual(id, 'requestId'); - assert.partialDeepStrictEqual(result, { id: 'setting test id' }); - }); - - it('correctly identifies a call to create a visitor via the LivechatCreator', { timeout: 15_000 }, async () => { - const livechatBridge = manager.getBridges().getLivechatBridge(); - const doCreateVisitorSpy = mock.method(livechatBridge, 'doCreateVisitor', () => Promise.resolve('random id')); - - const { id, result } = await controller['handleAccessorMessage']({ - type: rpcTypeRequest, - payload: { - jsonrpc: '2.0', - id: 'requestId', - method: 'accessor:getModifier:getCreator:getLivechatCreator:createVisitor', - params: [ - { - id: 'random id', - token: 'random token', - username: 'random username for visitor', - name: 'Random Visitor', - }, - ], - serialize: () => '', - }, - }); - - assert.strictEqual(doCreateVisitorSpy.mock.calls.length, 1); - assert.deepStrictEqual(doCreateVisitorSpy.mock.calls[0].arguments, [ - { - id: 'random id', - token: 'random token', - username: 'random username for visitor', - name: 'Random Visitor', - }, - '9c1d62ca-e40f-456f-8601-17c823a16c68', - ]); - - assert.strictEqual(id, 'requestId'); - assert.strictEqual(result, 'random id'); - }); - it('correctly identifies a call to the message bridge', { timeout: 15_000 }, async () => { const messageBridge = manager.getBridges().getMessageBridge(); const doCreateSpy = mock.method(messageBridge, 'doCreate', () => Promise.resolve('random-message-id')); From ac77da9373c910f1230a06d642a3f0f53e7ddc5e Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Jul 2026 21:44:38 +0000 Subject: [PATCH 3/3] refactor(apps): remove dead host accessor layer (Phase 5 / follow-up #4) The base-runtime is the single source of truth for accessor behavior and the accessor:* message category is gone (Phase 4), so the host copies of the accessors are unreachable. This removes them and un-threads the vestigial accessor manager from the sandbox-execution core. - Drop the ignored `accessors: AppAccessorManager` parameter from the run*/ runTheCode methods of AppApi, AppSlashCommand, AppVideoConfProvider and AppOutboundCommunicationProvider, and the `accessors` field from their four managers (the app executes in the subprocess via sendRequest; the host accessor manager was never consulted). - Delete AppAccessorManager, its managers/index export, and AppManager's accessorManager field/constructor/getAccessorManager/purifyApp usage (purifyApp only cleared caches that were never populated). - Delete src/server/accessors/ (64 files) and the now-orphaned src/server/misc/UIHelper.ts. - Adapt tests: delete tests/server/accessors/ and the AppAccessorManager test; strip getAccessorManager/.accessors setup and assertions from the affected manager, AppManager and Deno-runtime tests. Behavior-neutral: host tsc error-set unchanged vs baseline; host node suites green (excluding the two deno-spawn integration suites, which require the deno binary and run in CI). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_018FbxFGJWHiroxrdNPJRL3P --- .../apps-accessor-consolidation/README.md | 54 +++- packages/apps/src/server/AppManager.ts | 10 - .../apps/src/server/accessors/ApiExtend.ts | 15 - .../apps/src/server/accessors/AppAccessors.ts | 40 --- .../server/accessors/CloudWorkspaceRead.ts | 15 - .../server/accessors/ConfigurationExtend.ts | 26 -- .../server/accessors/ConfigurationModify.ts | 14 - .../src/server/accessors/ContactCreator.ts | 25 -- .../apps/src/server/accessors/ContactRead.ts | 15 - .../src/server/accessors/DiscussionBuilder.ts | 48 --- .../apps/src/server/accessors/EmailCreator.ts | 15 - .../src/server/accessors/EnvironmentRead.ts | 26 -- .../src/server/accessors/EnvironmentWrite.ts | 16 - .../accessors/EnvironmentalVariableRead.ts | 22 -- .../src/server/accessors/ExperimentalRead.ts | 10 - .../accessors/ExternalComponentsExtend.ts | 15 - packages/apps/src/server/accessors/Http.ts | 78 ----- .../apps/src/server/accessors/HttpExtend.ts | 58 ---- .../src/server/accessors/LivechatCreator.ts | 43 --- .../accessors/LivechatMessageBuilder.ts | 192 ------------ .../apps/src/server/accessors/LivechatRead.ts | 79 ----- .../src/server/accessors/LivechatUpdater.ts | 36 --- .../src/server/accessors/MessageBuilder.ts | 225 -------------- .../src/server/accessors/MessageExtender.ts | 51 ---- .../apps/src/server/accessors/MessageRead.ts | 37 --- .../src/server/accessors/MessageUpdater.ts | 19 -- .../src/server/accessors/ModerationModify.ts | 24 -- packages/apps/src/server/accessors/Modify.ts | 93 ------ .../src/server/accessors/ModifyCreator.ts | 275 ------------------ .../src/server/accessors/ModifyDeleter.ts | 39 --- .../src/server/accessors/ModifyExtender.ts | 55 ---- .../src/server/accessors/ModifyUpdater.ts | 118 -------- .../apps/src/server/accessors/Notifier.ts | 54 ---- .../src/server/accessors/OAuthAppsModify.ts | 23 -- .../src/server/accessors/OAuthAppsReader.ts | 19 -- .../OutboundCommunicationProviderExtend.ts | 22 -- .../apps/src/server/accessors/Persistence.ts | 47 --- .../src/server/accessors/PersistenceRead.ts | 23 -- packages/apps/src/server/accessors/Reader.ts | 98 ------- .../apps/src/server/accessors/RoleRead.ts | 19 -- .../apps/src/server/accessors/RoomBuilder.ts | 155 ---------- .../apps/src/server/accessors/RoomExtender.ts | 57 ---- .../apps/src/server/accessors/RoomRead.ts | 112 ------- .../src/server/accessors/SchedulerExtend.ts | 15 - .../src/server/accessors/SchedulerModify.ts | 31 -- .../src/server/accessors/ServerSettingRead.ts | 38 --- .../server/accessors/ServerSettingUpdater.ts | 19 -- .../server/accessors/ServerSettingsModify.ts | 27 -- .../apps/src/server/accessors/SettingRead.ts | 26 -- .../src/server/accessors/SettingUpdater.ts | 67 ----- .../src/server/accessors/SettingsExtend.ts | 27 -- .../server/accessors/SlashCommandsExtend.ts | 15 - .../server/accessors/SlashCommandsModify.ts | 23 -- .../apps/src/server/accessors/ThreadRead.ts | 15 - .../apps/src/server/accessors/UIController.ts | 126 -------- .../apps/src/server/accessors/UIExtend.ts | 15 - .../src/server/accessors/UploadCreator.ts | 29 -- .../apps/src/server/accessors/UploadRead.ts | 25 -- .../apps/src/server/accessors/UserBuilder.ts | 74 ----- .../apps/src/server/accessors/UserRead.ts | 39 --- .../apps/src/server/accessors/UserUpdater.ts | 43 --- .../accessors/VideoConfProviderExtend.ts | 15 - .../accessors/VideoConferenceBuilder.ts | 83 ------ .../server/accessors/VideoConferenceExtend.ts | 65 ----- .../server/accessors/VideoConferenceRead.ts | 15 - packages/apps/src/server/accessors/index.ts | 97 ------ .../src/server/managers/AppAccessorManager.ts | 252 ---------------- packages/apps/src/server/managers/AppApi.ts | 3 +- .../apps/src/server/managers/AppApiManager.ts | 6 +- .../AppOutboundCommunicationProvider.ts | 10 +- ...AppOutboundCommunicationProviderManager.ts | 8 +- .../src/server/managers/AppSlashCommand.ts | 8 +- .../server/managers/AppSlashCommandManager.ts | 14 +- .../server/managers/AppVideoConfProvider.ts | 33 +-- .../managers/AppVideoConfProviderManager.ts | 18 +- packages/apps/src/server/managers/index.ts | 2 - packages/apps/src/server/misc/UIHelper.ts | 32 -- packages/apps/tests/server/AppManager.test.ts | 2 - .../server/accessors/AppAccessors.test.ts | 121 -------- .../accessors/ConfigurationExtend.test.ts | 56 ---- .../accessors/ConfigurationModify.test.ts | 27 -- .../server/accessors/EnvironmentRead.test.ts | 21 -- .../server/accessors/EnvironmentWrite.test.ts | 19 -- .../EnvironmentalVariableRead.test.ts | 28 -- .../apps/tests/server/accessors/Http.test.ts | 155 ---------- .../tests/server/accessors/HttpExtend.test.ts | 80 ----- .../server/accessors/MessageBuilder.test.ts | 134 --------- .../server/accessors/MessageExtender.test.ts | 41 --- .../server/accessors/MessageRead.test.ts | 48 --- .../tests/server/accessors/Modify.test.ts | 46 --- .../server/accessors/ModifyCreator.test.ts | 130 --------- .../server/accessors/ModifyExtender.test.ts | 77 ----- .../server/accessors/ModifyUpdater.test.ts | 140 --------- .../tests/server/accessors/Notifier.test.ts | 50 ---- .../server/accessors/Persistence.test.ts | 83 ------ .../server/accessors/PersistenceRead.test.ts | 27 -- .../tests/server/accessors/Reader.test.ts | 59 ---- .../server/accessors/RoomBuilder.test.ts | 92 ------ .../server/accessors/RoomExtender.test.ts | 47 --- .../tests/server/accessors/RoomRead.test.ts | 150 ---------- .../accessors/ServerSettingRead.test.ts | 41 --- .../accessors/ServerSettingsModify.test.ts | 54 ---- .../server/accessors/SettingRead.test.ts | 36 --- .../server/accessors/SettingUpdater.test.ts | 104 ------- .../server/accessors/SettingsExtend.test.ts | 54 ---- .../accessors/SlashCommandsExtend.test.ts | 47 --- .../accessors/SlashCommandsModify.test.ts | 40 --- .../server/accessors/UserBuilder.test.ts | 59 ---- .../tests/server/accessors/UserRead.test.ts | 46 --- .../accessors/VideoConfProviderExtend.test.ts | 38 --- .../accessors/VideoConferenceBuilder.test.ts | 101 ------- .../accessors/VideoConferenceExtend.test.ts | 76 ----- .../accessors/VideoConferenceRead.test.ts | 28 -- .../managers/AppAccessorManager.test.ts | 174 ----------- .../server/managers/AppApiManager.test.ts | 10 +- .../managers/AppListenerManager.test.ts | 1 - ...tboundCommunicationProviderManager.test.ts | 10 +- .../managers/AppSettingsManager.test.ts | 9 +- .../managers/AppSlashCommandManager.test.ts | 10 +- .../AppVideoConfProviderManager.test.ts | 10 +- .../DenoRuntimeSubprocessController.test.ts | 5 +- .../SecureFieldsCodecCompatibility.test.ts | 5 +- 122 files changed, 84 insertions(+), 6239 deletions(-) delete mode 100644 packages/apps/src/server/accessors/ApiExtend.ts delete mode 100644 packages/apps/src/server/accessors/AppAccessors.ts delete mode 100644 packages/apps/src/server/accessors/CloudWorkspaceRead.ts delete mode 100644 packages/apps/src/server/accessors/ConfigurationExtend.ts delete mode 100644 packages/apps/src/server/accessors/ConfigurationModify.ts delete mode 100644 packages/apps/src/server/accessors/ContactCreator.ts delete mode 100644 packages/apps/src/server/accessors/ContactRead.ts delete mode 100644 packages/apps/src/server/accessors/DiscussionBuilder.ts delete mode 100644 packages/apps/src/server/accessors/EmailCreator.ts delete mode 100644 packages/apps/src/server/accessors/EnvironmentRead.ts delete mode 100644 packages/apps/src/server/accessors/EnvironmentWrite.ts delete mode 100644 packages/apps/src/server/accessors/EnvironmentalVariableRead.ts delete mode 100644 packages/apps/src/server/accessors/ExperimentalRead.ts delete mode 100644 packages/apps/src/server/accessors/ExternalComponentsExtend.ts delete mode 100644 packages/apps/src/server/accessors/Http.ts delete mode 100644 packages/apps/src/server/accessors/HttpExtend.ts delete mode 100644 packages/apps/src/server/accessors/LivechatCreator.ts delete mode 100644 packages/apps/src/server/accessors/LivechatMessageBuilder.ts delete mode 100644 packages/apps/src/server/accessors/LivechatRead.ts delete mode 100644 packages/apps/src/server/accessors/LivechatUpdater.ts delete mode 100644 packages/apps/src/server/accessors/MessageBuilder.ts delete mode 100644 packages/apps/src/server/accessors/MessageExtender.ts delete mode 100644 packages/apps/src/server/accessors/MessageRead.ts delete mode 100644 packages/apps/src/server/accessors/MessageUpdater.ts delete mode 100644 packages/apps/src/server/accessors/ModerationModify.ts delete mode 100644 packages/apps/src/server/accessors/Modify.ts delete mode 100644 packages/apps/src/server/accessors/ModifyCreator.ts delete mode 100644 packages/apps/src/server/accessors/ModifyDeleter.ts delete mode 100644 packages/apps/src/server/accessors/ModifyExtender.ts delete mode 100644 packages/apps/src/server/accessors/ModifyUpdater.ts delete mode 100644 packages/apps/src/server/accessors/Notifier.ts delete mode 100644 packages/apps/src/server/accessors/OAuthAppsModify.ts delete mode 100644 packages/apps/src/server/accessors/OAuthAppsReader.ts delete mode 100644 packages/apps/src/server/accessors/OutboundCommunicationProviderExtend.ts delete mode 100644 packages/apps/src/server/accessors/Persistence.ts delete mode 100644 packages/apps/src/server/accessors/PersistenceRead.ts delete mode 100644 packages/apps/src/server/accessors/Reader.ts delete mode 100644 packages/apps/src/server/accessors/RoleRead.ts delete mode 100644 packages/apps/src/server/accessors/RoomBuilder.ts delete mode 100644 packages/apps/src/server/accessors/RoomExtender.ts delete mode 100644 packages/apps/src/server/accessors/RoomRead.ts delete mode 100644 packages/apps/src/server/accessors/SchedulerExtend.ts delete mode 100644 packages/apps/src/server/accessors/SchedulerModify.ts delete mode 100644 packages/apps/src/server/accessors/ServerSettingRead.ts delete mode 100644 packages/apps/src/server/accessors/ServerSettingUpdater.ts delete mode 100644 packages/apps/src/server/accessors/ServerSettingsModify.ts delete mode 100644 packages/apps/src/server/accessors/SettingRead.ts delete mode 100644 packages/apps/src/server/accessors/SettingUpdater.ts delete mode 100644 packages/apps/src/server/accessors/SettingsExtend.ts delete mode 100644 packages/apps/src/server/accessors/SlashCommandsExtend.ts delete mode 100644 packages/apps/src/server/accessors/SlashCommandsModify.ts delete mode 100644 packages/apps/src/server/accessors/ThreadRead.ts delete mode 100644 packages/apps/src/server/accessors/UIController.ts delete mode 100644 packages/apps/src/server/accessors/UIExtend.ts delete mode 100644 packages/apps/src/server/accessors/UploadCreator.ts delete mode 100644 packages/apps/src/server/accessors/UploadRead.ts delete mode 100644 packages/apps/src/server/accessors/UserBuilder.ts delete mode 100644 packages/apps/src/server/accessors/UserRead.ts delete mode 100644 packages/apps/src/server/accessors/UserUpdater.ts delete mode 100644 packages/apps/src/server/accessors/VideoConfProviderExtend.ts delete mode 100644 packages/apps/src/server/accessors/VideoConferenceBuilder.ts delete mode 100644 packages/apps/src/server/accessors/VideoConferenceExtend.ts delete mode 100644 packages/apps/src/server/accessors/VideoConferenceRead.ts delete mode 100644 packages/apps/src/server/accessors/index.ts delete mode 100644 packages/apps/src/server/managers/AppAccessorManager.ts delete mode 100644 packages/apps/src/server/misc/UIHelper.ts delete mode 100644 packages/apps/tests/server/accessors/AppAccessors.test.ts delete mode 100644 packages/apps/tests/server/accessors/ConfigurationExtend.test.ts delete mode 100644 packages/apps/tests/server/accessors/ConfigurationModify.test.ts delete mode 100644 packages/apps/tests/server/accessors/EnvironmentRead.test.ts delete mode 100644 packages/apps/tests/server/accessors/EnvironmentWrite.test.ts delete mode 100644 packages/apps/tests/server/accessors/EnvironmentalVariableRead.test.ts delete mode 100644 packages/apps/tests/server/accessors/Http.test.ts delete mode 100644 packages/apps/tests/server/accessors/HttpExtend.test.ts delete mode 100644 packages/apps/tests/server/accessors/MessageBuilder.test.ts delete mode 100644 packages/apps/tests/server/accessors/MessageExtender.test.ts delete mode 100644 packages/apps/tests/server/accessors/MessageRead.test.ts delete mode 100644 packages/apps/tests/server/accessors/Modify.test.ts delete mode 100644 packages/apps/tests/server/accessors/ModifyCreator.test.ts delete mode 100644 packages/apps/tests/server/accessors/ModifyExtender.test.ts delete mode 100644 packages/apps/tests/server/accessors/ModifyUpdater.test.ts delete mode 100644 packages/apps/tests/server/accessors/Notifier.test.ts delete mode 100644 packages/apps/tests/server/accessors/Persistence.test.ts delete mode 100644 packages/apps/tests/server/accessors/PersistenceRead.test.ts delete mode 100644 packages/apps/tests/server/accessors/Reader.test.ts delete mode 100644 packages/apps/tests/server/accessors/RoomBuilder.test.ts delete mode 100644 packages/apps/tests/server/accessors/RoomExtender.test.ts delete mode 100644 packages/apps/tests/server/accessors/RoomRead.test.ts delete mode 100644 packages/apps/tests/server/accessors/ServerSettingRead.test.ts delete mode 100644 packages/apps/tests/server/accessors/ServerSettingsModify.test.ts delete mode 100644 packages/apps/tests/server/accessors/SettingRead.test.ts delete mode 100644 packages/apps/tests/server/accessors/SettingUpdater.test.ts delete mode 100644 packages/apps/tests/server/accessors/SettingsExtend.test.ts delete mode 100644 packages/apps/tests/server/accessors/SlashCommandsExtend.test.ts delete mode 100644 packages/apps/tests/server/accessors/SlashCommandsModify.test.ts delete mode 100644 packages/apps/tests/server/accessors/UserBuilder.test.ts delete mode 100644 packages/apps/tests/server/accessors/UserRead.test.ts delete mode 100644 packages/apps/tests/server/accessors/VideoConfProviderExtend.test.ts delete mode 100644 packages/apps/tests/server/accessors/VideoConferenceBuilder.test.ts delete mode 100644 packages/apps/tests/server/accessors/VideoConferenceExtend.test.ts delete mode 100644 packages/apps/tests/server/accessors/VideoConferenceRead.test.ts delete mode 100644 packages/apps/tests/server/managers/AppAccessorManager.test.ts diff --git a/docs/proposals/apps-accessor-consolidation/README.md b/docs/proposals/apps-accessor-consolidation/README.md index e9cab1201cde4..65357a40b3a18 100644 --- a/docs/proposals/apps-accessor-consolidation/README.md +++ b/docs/proposals/apps-accessor-consolidation/README.md @@ -485,13 +485,13 @@ since consolidating more logic into the runtime makes the assumption more load-b dropping. 3. **`messenger.sendRequest` timeout** — the runtime-side TODO becomes more prominent once all accessor traffic flows through it. -4. **Drop the legacy `_accessors` threading + delete the dead host accessor layer.** Un-thread the - ignored `accessors: AppAccessorManager` parameter from `AppApi.runExecutor`, - `AppSlashCommand`/`AppVideoConfProvider`/`AppOutboundCommunicationProvider` `run*`/`runTheCode` and - their managers; then delete `AppAccessorManager` (+ its `getAccessorManager()` on `AppManager` and - the `purifyApp` call), the entire `src/server/accessors/` directory (now unreachable from the - subprocess after Phase 4), the host `src/server/misc/UIHelper.ts` copy (its only importers are - those deleted accessors), and the `managers/index.ts` export. Behavior-neutral cleanup; kept +4. ✅ **Drop the legacy `_accessors` threading + delete the dead host accessor layer.** — **landed as + Phase 5** (§8). Un-threaded the ignored `accessors: AppAccessorManager` parameter from + `AppApi.runExecutor`, `AppSlashCommand`/`AppVideoConfProvider`/`AppOutboundCommunicationProvider` + `run*`/`runTheCode` and their managers; deleted `AppAccessorManager` (+ its `getAccessorManager()` + on `AppManager` and the `purifyApp` call), the entire `src/server/accessors/` directory (unreachable + from the subprocess after Phase 4), the host `src/server/misc/UIHelper.ts` copy (its only importers + were those deleted accessors), and the `managers/index.ts` export. Behavior-neutral cleanup; kept separate from the Phase 4 message-path teardown because it touches the sandbox-execution core. (The parity harness is **not** removed — it became a permanent test utility the base-runtime accessor tests depend on.) @@ -716,4 +716,42 @@ rather than removed). **End state (primary objectives met):** `BaseRuntimeSubprocessController` handles exactly one app-originated RPC category — `bridges:*` — with a single dispatcher and a single permission model, and accessor *behavior* lives in exactly one place, `packages/apps/base-runtime`. `handleAccessorMessage` -and the entire `accessor:*` category are gone. What remains is dead-code removal (follow-up #4). +and the entire `accessor:*` category are gone. What remains is dead-code removal (Phase 5 / follow-up #4). + +### Phase 5 — Dead host accessor layer removal (follow-up #4) — ✅ landed + +Physical removal of the now-unreachable host accessor code. Behavior-neutral: nothing on the +subprocess path reached any of it after Phase 4. + +1. ✅ **Un-threaded the vestigial `accessors` parameter** from the sandbox-execution core. The + `run*`/`runTheCode` methods already ignored it (`_accessors`) — the app executes in the subprocess + via `getRuntimeController().sendRequest`, so the host-side accessor manager was never consulted. + Dropped the parameter from `AppApi.runExecutor`, `AppSlashCommand.runExecutorOrPreviewer`/ + `runPreviewExecutor`/`runTheCode`, all `AppVideoConfProvider.run*`/`runTheCode`, and + `AppOutboundCommunicationProvider.runGetProviderMetadata`/`runSendOutboundMessage`/`runTheCode`, and + updated the four managers' call sites. Removed the now-unused `private readonly accessors` field + (and its `this.manager.getAccessorManager()` assignment) from `AppApiManager`, + `AppSlashCommandManager`, `AppVideoConfProviderManager`, and `AppOutboundCommunicationProviderManager`. +2. ✅ **Deleted `AppAccessorManager`** (`src/server/managers/AppAccessorManager.ts`), removed its + `managers/index.ts` export, and removed `AppManager`'s `accessorManager` field, its + `new AppAccessorManager(this)` construction, the `getAccessorManager()` accessor, and the + `accessorManager.purifyApp(...)` call in `removeLocal` (a no-op — the caches it cleared were never + populated once no host code called `getReader`/`getModifier`/etc.). +3. ✅ **Deleted the entire `src/server/accessors/` directory** (64 files — the host copies of the + readers, modifiers, builders, environment accessors, and the configuration/registration accessors) + and the host `src/server/misc/UIHelper.ts` (only ever imported by those deleted accessors). The + base-runtime holds the single source of truth for all of this. +4. ✅ **Adapted tests:** deleted `tests/server/accessors/` (35 host-accessor unit tests — the + base-runtime suites cover the equivalent behavior) and `tests/server/managers/AppAccessorManager.test.ts`; + removed the `AppAccessorManager`/`getAccessorManager()`/`(x as any).accessors` setup and assertions + from the four manager tests, `AppSettingsManager.test.ts`, `AppManager.test.ts`, the two Deno-runtime + integration tests, and `AppListenerManager.test.ts`. + +**Verification:** host `tsc` error-set unchanged vs the environmental-only baseline (no new errors); +`test:node` host suites green (excluding the two `deno`-spawn integration suites, which require the +`deno` binary unavailable in this environment); base-runtime suite unaffected (untouched by this phase). + +**End state:** the `@rocket.chat/apps` host no longer contains any accessor implementation or accessor +manager. The only accessor-shaped code left on the host is the bridge layer (`AppBridges`/`do*`) and +`AppResourceBridge`; every accessor an app actually uses is built and resolved inside +`packages/apps/base-runtime`. diff --git a/packages/apps/src/server/AppManager.ts b/packages/apps/src/server/AppManager.ts index ce5656a3b62f8..fe60b52603d03 100644 --- a/packages/apps/src/server/AppManager.ts +++ b/packages/apps/src/server/AppManager.ts @@ -17,7 +17,6 @@ import { AppCompiler, AppFabricationFulfillment, AppPackageParser } from './comp import { InvalidLicenseError } from './errors'; import { InvalidInstallationError } from './errors/InvalidInstallationError'; import { - AppAccessorManager, AppApiManager, AppExternalComponentManager, AppLicenseManager, @@ -87,8 +86,6 @@ export class AppManager { private readonly compiler: AppCompiler; - private readonly accessorManager: AppAccessorManager; - private readonly listenerManager: AppListenerManager; private readonly commandManager: AppSlashCommandManager; @@ -153,7 +150,6 @@ export class AppManager { this.parser = new AppPackageParser(); this.compiler = new AppCompiler(); - this.accessorManager = new AppAccessorManager(this); this.listenerManager = new AppListenerManager(this); this.commandManager = new AppSlashCommandManager(this); this.apiManager = new AppApiManager(this); @@ -200,11 +196,6 @@ export class AppManager { return this.compiler; } - /** Gets the accessor manager instance. */ - public getAccessorManager(): AppAccessorManager { - return this.accessorManager; - } - /** Gets the instance of the Bridge manager. */ public getBridges(): AppBridges { return this.bridges; @@ -1096,7 +1087,6 @@ export class AppManager { this.listenerManager.lockEssentialEvents(app); this.externalComponentManager.unregisterExternalComponents(app.getID()); await this.apiManager.unregisterApis(app.getID()); - this.accessorManager.purifyApp(app.getID()); this.uiActionButtonManager.clearAppActionButtons(app.getID()); await this.videoConfProviderManager.unregisterProviders(app.getID()); await this.outboundCommunicationProviderManager.unregisterProviders(app.getID(), { diff --git a/packages/apps/src/server/accessors/ApiExtend.ts b/packages/apps/src/server/accessors/ApiExtend.ts deleted file mode 100644 index 46e9eeab782bc..0000000000000 --- a/packages/apps/src/server/accessors/ApiExtend.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { IApiExtend } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IApi } from '@rocket.chat/apps-engine/definition/api'; - -import type { AppApiManager } from '../managers/AppApiManager'; - -export class ApiExtend implements IApiExtend { - constructor( - private readonly manager: AppApiManager, - private readonly appId: string, - ) {} - - public provideApi(api: IApi): Promise { - return Promise.resolve(this.manager.addApi(this.appId, api)); - } -} diff --git a/packages/apps/src/server/accessors/AppAccessors.ts b/packages/apps/src/server/accessors/AppAccessors.ts deleted file mode 100644 index 0959de4db4fea..0000000000000 --- a/packages/apps/src/server/accessors/AppAccessors.ts +++ /dev/null @@ -1,40 +0,0 @@ -import type { IAppAccessors, IEnvironmentRead, IEnvironmentWrite, IHttp, IRead } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IApiEndpointMetadata } from '@rocket.chat/apps-engine/definition/api'; - -import type { AppManager } from '../AppManager'; -import type { AppAccessorManager } from '../managers/AppAccessorManager'; -import type { AppApiManager } from '../managers/AppApiManager'; - -export class AppAccessors implements IAppAccessors { - private accessorManager: AppAccessorManager; - - private apiManager: AppApiManager; - - constructor( - manager: AppManager, - private readonly appId: string, - ) { - this.accessorManager = manager.getAccessorManager(); - this.apiManager = manager.getApiManager(); - } - - public get environmentReader(): IEnvironmentRead { - return this.accessorManager.getEnvironmentRead(this.appId); - } - - public get environmentWriter(): IEnvironmentWrite { - return this.accessorManager.getEnvironmentWrite(this.appId); - } - - public get reader(): IRead { - return this.accessorManager.getReader(this.appId); - } - - public get http(): IHttp { - return this.accessorManager.getHttp(this.appId); - } - - public get providedApiEndpoints(): Array { - return this.apiManager.listApis(this.appId); - } -} diff --git a/packages/apps/src/server/accessors/CloudWorkspaceRead.ts b/packages/apps/src/server/accessors/CloudWorkspaceRead.ts deleted file mode 100644 index 999ec62a9110a..0000000000000 --- a/packages/apps/src/server/accessors/CloudWorkspaceRead.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { ICloudWorkspaceRead } from '@rocket.chat/apps-engine/definition/accessors/ICloudWorkspaceRead'; -import type { IWorkspaceToken } from '@rocket.chat/apps-engine/definition/cloud/IWorkspaceToken'; - -import type { CloudWorkspaceBridge } from '../bridges/CloudWorkspaceBridge'; - -export class CloudWorkspaceRead implements ICloudWorkspaceRead { - constructor( - private readonly cloudBridge: CloudWorkspaceBridge, - private readonly appId: string, - ) {} - - public async getWorkspaceToken(scope: string): Promise { - return this.cloudBridge.doGetWorkspaceToken(scope, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/ConfigurationExtend.ts b/packages/apps/src/server/accessors/ConfigurationExtend.ts deleted file mode 100644 index a1629114efd20..0000000000000 --- a/packages/apps/src/server/accessors/ConfigurationExtend.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { - IApiExtend, - IConfigurationExtend, - IExternalComponentsExtend, - IHttpExtend, - ISchedulerExtend, - ISettingsExtend, - ISlashCommandsExtend, - IUIExtend, - IVideoConfProvidersExtend, - IOutboundCommunicationProviderExtend, -} from '@rocket.chat/apps-engine/definition/accessors'; - -export class ConfigurationExtend implements IConfigurationExtend { - constructor( - public readonly http: IHttpExtend, - public readonly settings: ISettingsExtend, - public readonly slashCommands: ISlashCommandsExtend, - public readonly api: IApiExtend, - public readonly externalComponents: IExternalComponentsExtend, - public readonly scheduler: ISchedulerExtend, - public readonly ui: IUIExtend, - public readonly videoConfProviders: IVideoConfProvidersExtend, - public readonly outboundCommunication: IOutboundCommunicationProviderExtend, - ) {} -} diff --git a/packages/apps/src/server/accessors/ConfigurationModify.ts b/packages/apps/src/server/accessors/ConfigurationModify.ts deleted file mode 100644 index 66de60bb0d93a..0000000000000 --- a/packages/apps/src/server/accessors/ConfigurationModify.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { - IConfigurationModify, - ISchedulerModify, - IServerSettingsModify, - ISlashCommandsModify, -} from '@rocket.chat/apps-engine/definition/accessors'; - -export class ConfigurationModify implements IConfigurationModify { - constructor( - public readonly serverSettings: IServerSettingsModify, - public readonly slashCommands: ISlashCommandsModify, - public readonly scheduler: ISchedulerModify, - ) {} -} diff --git a/packages/apps/src/server/accessors/ContactCreator.ts b/packages/apps/src/server/accessors/ContactCreator.ts deleted file mode 100644 index 26d66414052d9..0000000000000 --- a/packages/apps/src/server/accessors/ContactCreator.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { IContactCreator } from '@rocket.chat/apps-engine/definition/accessors/IContactCreator'; -import type { ILivechatContact } from '@rocket.chat/apps-engine/definition/livechat'; - -import type { AppBridges } from '../bridges'; - -export class ContactCreator implements IContactCreator { - constructor( - private readonly bridges: AppBridges, - private readonly appId: string, - ) {} - - verifyContact(verifyContactChannelParams: { - contactId: string; - field: string; - value: string; - visitorId: string; - roomId: string; - }): Promise { - return this.bridges.getContactBridge().doVerifyContact(verifyContactChannelParams, this.appId); - } - - addContactEmail(contactId: ILivechatContact['_id'], email: string): Promise { - return this.bridges.getContactBridge().doAddContactEmail(contactId, email, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/ContactRead.ts b/packages/apps/src/server/accessors/ContactRead.ts deleted file mode 100644 index c950bca5d1327..0000000000000 --- a/packages/apps/src/server/accessors/ContactRead.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { IContactRead } from '@rocket.chat/apps-engine/definition/accessors/IContactRead'; -import type { ILivechatContact } from '@rocket.chat/apps-engine/definition/livechat'; - -import type { AppBridges } from '../bridges'; - -export class ContactRead implements IContactRead { - constructor( - private readonly bridges: AppBridges, - private readonly appId: string, - ) {} - - public getById(contactId: ILivechatContact['_id']): Promise { - return this.bridges.getContactBridge().doGetById(contactId, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/DiscussionBuilder.ts b/packages/apps/src/server/accessors/DiscussionBuilder.ts deleted file mode 100644 index 38391c871d928..0000000000000 --- a/packages/apps/src/server/accessors/DiscussionBuilder.ts +++ /dev/null @@ -1,48 +0,0 @@ -import type { IDiscussionBuilder } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IMessage } from '@rocket.chat/apps-engine/definition/messages'; -import { RocketChatAssociationModel } from '@rocket.chat/apps-engine/definition/metadata'; -import { RoomType } from '@rocket.chat/apps-engine/definition/rooms'; -import type { IRoom } from '@rocket.chat/apps-engine/definition/rooms/IRoom'; - -import { RoomBuilder } from './RoomBuilder'; - -export class DiscussionBuilder extends RoomBuilder implements IDiscussionBuilder { - public declare kind: RocketChatAssociationModel.DISCUSSION; - - private reply: string; - - private parentMessage: IMessage; - - constructor(data?: Partial) { - super(data); - this.kind = RocketChatAssociationModel.DISCUSSION; - this.room.type = RoomType.PRIVATE_GROUP; - } - - public setParentRoom(parentRoom: IRoom): IDiscussionBuilder { - this.room.parentRoom = parentRoom; - return this; - } - - public getParentRoom(): IRoom { - return this.room.parentRoom; - } - - public setReply(reply: string): IDiscussionBuilder { - this.reply = reply; - return this; - } - - public getReply(): string { - return this.reply; - } - - public setParentMessage(parentMessage: IMessage): IDiscussionBuilder { - this.parentMessage = parentMessage; - return this; - } - - public getParentMessage(): IMessage { - return this.parentMessage; - } -} diff --git a/packages/apps/src/server/accessors/EmailCreator.ts b/packages/apps/src/server/accessors/EmailCreator.ts deleted file mode 100644 index 921378ed8504d..0000000000000 --- a/packages/apps/src/server/accessors/EmailCreator.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { IEmailCreator } from '@rocket.chat/apps-engine/definition/accessors/IEmailCreator'; -import type { IEmail } from '@rocket.chat/apps-engine/definition/email'; - -import type { AppBridges } from '../bridges'; - -export class EmailCreator implements IEmailCreator { - constructor( - private readonly bridges: AppBridges, - private readonly appId: string, - ) {} - - public async send(email: IEmail): Promise { - return this.bridges.getEmailBridge().doSendEmail(email, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/EnvironmentRead.ts b/packages/apps/src/server/accessors/EnvironmentRead.ts deleted file mode 100644 index 8400a2c79a4de..0000000000000 --- a/packages/apps/src/server/accessors/EnvironmentRead.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { - IEnvironmentalVariableRead, - IEnvironmentRead, - IServerSettingRead, - ISettingRead, -} from '@rocket.chat/apps-engine/definition/accessors'; - -export class EnvironmentRead implements IEnvironmentRead { - constructor( - private readonly settings: ISettingRead, - private readonly serverSettings: IServerSettingRead, - private readonly envRead: IEnvironmentalVariableRead, - ) {} - - public getSettings(): ISettingRead { - return this.settings; - } - - public getServerSettings(): IServerSettingRead { - return this.serverSettings; - } - - public getEnvironmentVariables(): IEnvironmentalVariableRead { - return this.envRead; - } -} diff --git a/packages/apps/src/server/accessors/EnvironmentWrite.ts b/packages/apps/src/server/accessors/EnvironmentWrite.ts deleted file mode 100644 index d13bc5b834f64..0000000000000 --- a/packages/apps/src/server/accessors/EnvironmentWrite.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { IEnvironmentWrite, IServerSettingUpdater, ISettingUpdater } from '@rocket.chat/apps-engine/definition/accessors'; - -export class EnvironmentWrite implements IEnvironmentWrite { - constructor( - private readonly settings: ISettingUpdater, - private readonly serverSettings: IServerSettingUpdater, - ) {} - - public getSettings(): ISettingUpdater { - return this.settings; - } - - public getServerSettings(): IServerSettingUpdater { - return this.serverSettings; - } -} diff --git a/packages/apps/src/server/accessors/EnvironmentalVariableRead.ts b/packages/apps/src/server/accessors/EnvironmentalVariableRead.ts deleted file mode 100644 index c8e45f936b6f6..0000000000000 --- a/packages/apps/src/server/accessors/EnvironmentalVariableRead.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { IEnvironmentalVariableRead } from '@rocket.chat/apps-engine/definition/accessors'; - -import type { EnvironmentalVariableBridge } from '../bridges'; - -export class EnvironmentalVariableRead implements IEnvironmentalVariableRead { - constructor( - private readonly bridge: EnvironmentalVariableBridge, - private readonly appId: string, - ) {} - - public getValueByName(envVarName: string): Promise { - return this.bridge.doGetValueByName(envVarName, this.appId); - } - - public isReadable(envVarName: string): Promise { - return this.bridge.doIsReadable(envVarName, this.appId); - } - - public isSet(envVarName: string): Promise { - return this.bridge.doIsSet(envVarName, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/ExperimentalRead.ts b/packages/apps/src/server/accessors/ExperimentalRead.ts deleted file mode 100644 index 0b76281d9e405..0000000000000 --- a/packages/apps/src/server/accessors/ExperimentalRead.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { IExperimentalRead } from '@rocket.chat/apps-engine/definition/accessors'; - -import type { ExperimentalBridge } from '../bridges'; - -export class ExperimentalRead implements IExperimentalRead { - constructor( - protected readonly experimentalBridge: ExperimentalBridge, - protected readonly appId: string, - ) {} -} diff --git a/packages/apps/src/server/accessors/ExternalComponentsExtend.ts b/packages/apps/src/server/accessors/ExternalComponentsExtend.ts deleted file mode 100644 index 8acfdff1d3317..0000000000000 --- a/packages/apps/src/server/accessors/ExternalComponentsExtend.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { IExternalComponentsExtend } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IExternalComponent } from '@rocket.chat/apps-engine/definition/externalComponent/IExternalComponent'; - -import type { AppExternalComponentManager } from '../managers/AppExternalComponentManager'; - -export class ExternalComponentsExtend implements IExternalComponentsExtend { - constructor( - private readonly manager: AppExternalComponentManager, - private readonly appId: string, - ) {} - - public async register(externalComponent: IExternalComponent): Promise { - return Promise.resolve(this.manager.addExternalComponent(this.appId, externalComponent)); - } -} diff --git a/packages/apps/src/server/accessors/Http.ts b/packages/apps/src/server/accessors/Http.ts deleted file mode 100644 index aa9bcf403cd9b..0000000000000 --- a/packages/apps/src/server/accessors/Http.ts +++ /dev/null @@ -1,78 +0,0 @@ -import type { IHttp, IHttpExtend, IHttpRequest, IHttpResponse } from '@rocket.chat/apps-engine/definition/accessors'; -import { RequestMethod } from '@rocket.chat/apps-engine/definition/accessors'; - -import type { AppBridges } from '../bridges/AppBridges'; -import type { AppAccessorManager } from '../managers/AppAccessorManager'; - -export class Http implements IHttp { - constructor( - private readonly accessManager: AppAccessorManager, - private readonly bridges: AppBridges, - private readonly httpExtender: IHttpExtend, - private readonly appId: string, - ) {} - - public get(url: string, options?: IHttpRequest): Promise { - return this._processHandler(url, RequestMethod.GET, options); - } - - public put(url: string, options?: IHttpRequest): Promise { - return this._processHandler(url, RequestMethod.PUT, options); - } - - public post(url: string, options?: IHttpRequest): Promise { - return this._processHandler(url, RequestMethod.POST, options); - } - - public del(url: string, options?: IHttpRequest): Promise { - return this._processHandler(url, RequestMethod.DELETE, options); - } - - public patch(url: string, options?: IHttpRequest): Promise { - return this._processHandler(url, RequestMethod.PATCH, options); - } - - private async _processHandler(url: string, method: RequestMethod, options?: IHttpRequest): Promise { - let request = options || {}; - - if (typeof request.headers === 'undefined') { - request.headers = {}; - } - - this.httpExtender.getDefaultHeaders().forEach((value: string, key: string) => { - if (typeof request.headers[key] !== 'string') { - request.headers[key] = value; - } - }); - - if (typeof request.params === 'undefined') { - request.params = {}; - } - - this.httpExtender.getDefaultParams().forEach((value: string, key: string) => { - if (typeof request.params[key] !== 'string') { - request.params[key] = value; - } - }); - - const reader = this.accessManager.getReader(this.appId); - const persis = this.accessManager.getPersistence(this.appId); - - for (const handler of this.httpExtender.getPreRequestHandlers()) { - request = await handler.executePreHttpRequest(url, request, reader, persis); - } - - let response = await this.bridges.getHttpBridge().doCall({ - appId: this.appId, - method, - url, - request, - }); - - for (const handler of this.httpExtender.getPreResponseHandlers()) { - response = await handler.executePreHttpResponse(response, reader, persis); - } - - return response; - } -} diff --git a/packages/apps/src/server/accessors/HttpExtend.ts b/packages/apps/src/server/accessors/HttpExtend.ts deleted file mode 100644 index 98311a633577b..0000000000000 --- a/packages/apps/src/server/accessors/HttpExtend.ts +++ /dev/null @@ -1,58 +0,0 @@ -import type { IHttpExtend, IHttpPreRequestHandler, IHttpPreResponseHandler } from '@rocket.chat/apps-engine/definition/accessors'; - -export class HttpExtend implements IHttpExtend { - private headers: Map; - - private params: Map; - - private requests: Array; - - private responses: Array; - - constructor() { - this.headers = new Map(); - this.params = new Map(); - this.requests = []; - this.responses = []; - } - - public provideDefaultHeader(key: string, value: string): void { - this.headers.set(key, value); - } - - public provideDefaultHeaders(headers: { [key: string]: string }): void { - Object.keys(headers).forEach((key) => this.headers.set(key, headers[key])); - } - - public provideDefaultParam(key: string, value: string): void { - this.params.set(key, value); - } - - public provideDefaultParams(params: { [key: string]: string }): void { - Object.keys(params).forEach((key) => this.params.set(key, params[key])); - } - - public providePreRequestHandler(handler: IHttpPreRequestHandler): void { - this.requests.push(handler); - } - - public providePreResponseHandler(handler: IHttpPreResponseHandler): void { - this.responses.push(handler); - } - - public getDefaultHeaders(): Map { - return new Map(this.headers); - } - - public getDefaultParams(): Map { - return new Map(this.params); - } - - public getPreRequestHandlers(): Array { - return Array.from(this.requests); - } - - public getPreResponseHandlers(): Array { - return Array.from(this.responses); - } -} diff --git a/packages/apps/src/server/accessors/LivechatCreator.ts b/packages/apps/src/server/accessors/LivechatCreator.ts deleted file mode 100644 index df51bb1debabb..0000000000000 --- a/packages/apps/src/server/accessors/LivechatCreator.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { randomBytes } from 'node:crypto'; - -import type { ILivechatCreator } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IExtraRoomParams } from '@rocket.chat/apps-engine/definition/accessors/ILivechatCreator'; -import type { ILivechatRoom } from '@rocket.chat/apps-engine/definition/livechat/ILivechatRoom'; -import type { - IVisitorExternalIdentifier, - IVisitor, - ResolveVisitorContactData, -} from '@rocket.chat/apps-engine/definition/livechat/IVisitor'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import type { AppBridges } from '../bridges'; - -export class LivechatCreator implements ILivechatCreator { - constructor( - private readonly bridges: AppBridges, - private readonly appId: string, - ) {} - - public resolveVisitor(externalId: IVisitorExternalIdentifier, contactData?: ResolveVisitorContactData): Promise { - return this.bridges.getLivechatBridge().doResolveVisitor(externalId, contactData, this.appId); - } - - public createRoom(visitor: IVisitor, agent: IUser, extraParams?: IExtraRoomParams): Promise { - return this.bridges.getLivechatBridge().doCreateRoom(visitor, agent, this.appId, extraParams); - } - - /** - * @deprecated Use `createAndReturnVisitor` instead. - */ - public createVisitor(visitor: IVisitor): Promise { - return this.bridges.getLivechatBridge().doCreateVisitor(visitor, this.appId); - } - - public createAndReturnVisitor(visitor: IVisitor): Promise { - return this.bridges.getLivechatBridge().doCreateAndReturnVisitor(visitor, this.appId); - } - - public createToken(): string { - return randomBytes(16).toString('hex'); // Ensures 128 bits of entropy - } -} diff --git a/packages/apps/src/server/accessors/LivechatMessageBuilder.ts b/packages/apps/src/server/accessors/LivechatMessageBuilder.ts deleted file mode 100644 index ffe02e3ed0997..0000000000000 --- a/packages/apps/src/server/accessors/LivechatMessageBuilder.ts +++ /dev/null @@ -1,192 +0,0 @@ -import type { ILivechatMessageBuilder, IMessageBuilder } from '@rocket.chat/apps-engine/definition/accessors'; -import type { ILivechatMessage } from '@rocket.chat/apps-engine/definition/livechat/ILivechatMessage'; -import type { IVisitor } from '@rocket.chat/apps-engine/definition/livechat/IVisitor'; -import type { IMessage, IMessageAttachment } from '@rocket.chat/apps-engine/definition/messages'; -import { RocketChatAssociationModel } from '@rocket.chat/apps-engine/definition/metadata'; -import type { IRoom } from '@rocket.chat/apps-engine/definition/rooms'; -import { RoomType } from '@rocket.chat/apps-engine/definition/rooms'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import { MessageBuilder } from './MessageBuilder'; - -export class LivechatMessageBuilder implements ILivechatMessageBuilder { - public kind: RocketChatAssociationModel.LIVECHAT_MESSAGE; - - private msg: ILivechatMessage; - - constructor(message?: ILivechatMessage) { - this.kind = RocketChatAssociationModel.LIVECHAT_MESSAGE; - this.msg = message || ({} as ILivechatMessage); - } - - public setData(data: ILivechatMessage): ILivechatMessageBuilder { - delete data.id; - this.msg = data; - - return this; - } - - public setRoom(room: IRoom): ILivechatMessageBuilder { - this.msg.room = room; - return this; - } - - public getRoom(): IRoom { - return this.msg.room; - } - - public setSender(sender: IUser): ILivechatMessageBuilder { - this.msg.sender = sender; - delete this.msg.visitor; - - return this; - } - - public getSender(): IUser { - return this.msg.sender; - } - - public setText(text: string): ILivechatMessageBuilder { - this.msg.text = text; - return this; - } - - public getText(): string { - return this.msg.text; - } - - public setEmojiAvatar(emoji: string): ILivechatMessageBuilder { - this.msg.emoji = emoji; - return this; - } - - public getEmojiAvatar(): string { - return this.msg.emoji; - } - - public setAvatarUrl(avatarUrl: string): ILivechatMessageBuilder { - this.msg.avatarUrl = avatarUrl; - return this; - } - - public getAvatarUrl(): string { - return this.msg.avatarUrl; - } - - public setUsernameAlias(alias: string): ILivechatMessageBuilder { - this.msg.alias = alias; - return this; - } - - public getUsernameAlias(): string { - return this.msg.alias; - } - - public addAttachment(attachment: IMessageAttachment): ILivechatMessageBuilder { - if (!this.msg.attachments) { - this.msg.attachments = []; - } - - this.msg.attachments.push(attachment); - return this; - } - - public setAttachments(attachments: Array): ILivechatMessageBuilder { - this.msg.attachments = attachments; - return this; - } - - public getAttachments(): Array { - return this.msg.attachments; - } - - public replaceAttachment(position: number, attachment: IMessageAttachment): ILivechatMessageBuilder { - if (!this.msg.attachments) { - this.msg.attachments = []; - } - - if (!this.msg.attachments[position]) { - throw new Error(`No attachment found at the index of "${position}" to replace.`); - } - - this.msg.attachments[position] = attachment; - return this; - } - - public removeAttachment(position: number): ILivechatMessageBuilder { - if (!this.msg.attachments) { - this.msg.attachments = []; - } - - if (!this.msg.attachments[position]) { - throw new Error(`No attachment found at the index of "${position}" to remove.`); - } - - this.msg.attachments.splice(position, 1); - - return this; - } - - public setEditor(user: IUser): ILivechatMessageBuilder { - this.msg.editor = user; - return this; - } - - public getEditor(): IUser { - return this.msg.editor; - } - - public setGroupable(groupable: boolean): ILivechatMessageBuilder { - this.msg.groupable = groupable; - return this; - } - - public getGroupable(): boolean { - return this.msg.groupable; - } - - public setParseUrls(parseUrls: boolean): ILivechatMessageBuilder { - this.msg.parseUrls = parseUrls; - return this; - } - - public getParseUrls(): boolean { - return this.msg.parseUrls; - } - - public setToken(token: string): ILivechatMessageBuilder { - this.msg.token = token; - return this; - } - - public getToken(): string { - return this.msg.token; - } - - public setVisitor(visitor: IVisitor): ILivechatMessageBuilder { - this.msg.visitor = visitor; - delete this.msg.sender; - - return this; - } - - public getVisitor(): IVisitor { - return this.msg.visitor; - } - - public getMessage(): ILivechatMessage { - if (!this.msg.room) { - throw new Error('The "room" property is required.'); - } - - if (this.msg.room.type !== RoomType.LIVE_CHAT) { - throw new Error('The room is not a Livechat room'); - } - - return this.msg; - } - - public getMessageBuilder(): IMessageBuilder { - return new MessageBuilder(this.msg as IMessage); - } -} diff --git a/packages/apps/src/server/accessors/LivechatRead.ts b/packages/apps/src/server/accessors/LivechatRead.ts deleted file mode 100644 index 6e5d5cd443163..0000000000000 --- a/packages/apps/src/server/accessors/LivechatRead.ts +++ /dev/null @@ -1,79 +0,0 @@ -import type { ILivechatRead } from '@rocket.chat/apps-engine/definition/accessors/ILivechatRead'; -import type { IDepartment } from '@rocket.chat/apps-engine/definition/livechat'; -import type { ILivechatRoom } from '@rocket.chat/apps-engine/definition/livechat/ILivechatRoom'; -import type { IVisitor } from '@rocket.chat/apps-engine/definition/livechat/IVisitor'; -import type { IMessage } from '@rocket.chat/apps-engine/definition/messages'; - -import type { LivechatBridge } from '../bridges/LivechatBridge'; - -export class LivechatRead implements ILivechatRead { - constructor( - private readonly livechatBridge: LivechatBridge, - private readonly appId: string, - ) {} - - /** - * @deprecated please use the `isOnlineAsync` method instead. - * In the next major, this method will be `async` - */ - public isOnline(departmentId?: string): boolean { - console.warn( - "The `LivechatRead.isOnline` method is deprecated and won't behave as intended. Please use `LivechatRead.isOnlineAsync` instead", - ); - - return this.livechatBridge.doIsOnline(departmentId, this.appId); - } - - public isOnlineAsync(departmentId?: string): Promise { - return this.livechatBridge.doIsOnlineAsync(departmentId, this.appId); - } - - public getDepartmentsEnabledWithAgents(): Promise> { - return this.livechatBridge.doFindDepartmentsEnabledWithAgents(this.appId); - } - - public getLivechatRooms(visitor: IVisitor, departmentId?: string): Promise> { - return this.livechatBridge.doFindRooms(visitor, departmentId, this.appId); - } - - public getLivechatTotalOpenRoomsByAgentId(agentId: string): Promise { - return this.livechatBridge.doCountOpenRoomsByAgentId(agentId, this.appId); - } - - public getLivechatOpenRoomsByAgentId(agentId: string): Promise> { - return this.livechatBridge.doFindOpenRoomsByAgentId(agentId, this.appId); - } - - /** - * @deprecated This method does not adhere to the conversion practices applied - * elsewhere in the Apps-Engine and will be removed in the next major version. - * Prefer the alternative methods to fetch visitors. - */ - public getLivechatVisitors(query: object): Promise> { - return this.livechatBridge.doFindVisitors(query, this.appId); - } - - public getLivechatVisitorById(id: string): Promise { - return this.livechatBridge.doFindVisitorById(id, this.appId); - } - - public getLivechatVisitorByEmail(email: string): Promise { - return this.livechatBridge.doFindVisitorByEmail(email, this.appId); - } - - public getLivechatVisitorByToken(token: string): Promise { - return this.livechatBridge.doFindVisitorByToken(token, this.appId); - } - - public getLivechatVisitorByPhoneNumber(phoneNumber: string): Promise { - return this.livechatBridge.doFindVisitorByPhoneNumber(phoneNumber, this.appId); - } - - public getLivechatDepartmentByIdOrName(value: string): Promise { - return this.livechatBridge.doFindDepartmentByIdOrName(value, this.appId); - } - - public _fetchLivechatRoomMessages(roomId: string): Promise> { - return this.livechatBridge.do_fetchLivechatRoomMessages(this.appId, roomId); - } -} diff --git a/packages/apps/src/server/accessors/LivechatUpdater.ts b/packages/apps/src/server/accessors/LivechatUpdater.ts deleted file mode 100644 index cc222bdc5a10b..0000000000000 --- a/packages/apps/src/server/accessors/LivechatUpdater.ts +++ /dev/null @@ -1,36 +0,0 @@ -import type { ILivechatUpdater } from '@rocket.chat/apps-engine/definition/accessors'; -import type { - ILivechatRoom, - ILivechatTransferData, - IVisitor, - IVisitorExternalIdentifier, -} from '@rocket.chat/apps-engine/definition/livechat'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import type { AppBridges } from '../bridges'; - -export class LivechatUpdater implements ILivechatUpdater { - constructor( - private readonly bridges: AppBridges, - private readonly appId: string, - ) {} - - public transferVisitor(visitor: IVisitor, transferData: ILivechatTransferData): Promise { - return this.bridges.getLivechatBridge().doTransferVisitor(visitor, transferData, this.appId); - } - - public closeRoom(room: ILivechatRoom, comment: string, closer?: IUser): Promise { - return this.bridges.getLivechatBridge().doCloseRoom(room, comment, closer, this.appId); - } - - public setCustomFields(token: IVisitor['token'], key: string, value: string, overwrite: boolean): Promise { - return this.bridges - .getLivechatBridge() - .doSetCustomFields({ token, key, value, overwrite }, this.appId) - .then((result) => result > 0); - } - - public updateVisitorExternalId(visitorId: string, externalId: Omit): Promise { - return this.bridges.getLivechatBridge().doUpdateVisitorExternalId(visitorId, externalId, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/MessageBuilder.ts b/packages/apps/src/server/accessors/MessageBuilder.ts deleted file mode 100644 index 9b6aaf3c1e0c6..0000000000000 --- a/packages/apps/src/server/accessors/MessageBuilder.ts +++ /dev/null @@ -1,225 +0,0 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion -- the builder works under the assumption that "gets" would only happen after the corresponding "sets" */ - -import type { IMessageBuilder } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IMessage, IMessageAttachment } from '@rocket.chat/apps-engine/definition/messages'; -import { RocketChatAssociationModel } from '@rocket.chat/apps-engine/definition/metadata'; -import type { IRoom } from '@rocket.chat/apps-engine/definition/rooms'; -import type { IBlock } from '@rocket.chat/apps-engine/definition/uikit'; -import { BlockBuilder } from '@rocket.chat/apps-engine/definition/uikit'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; -import type { LayoutBlock } from '@rocket.chat/ui-kit'; - -export class MessageBuilder implements IMessageBuilder { - public kind: RocketChatAssociationModel.MESSAGE; - - private msg: IMessage; - - constructor(message?: IMessage) { - this.kind = RocketChatAssociationModel.MESSAGE; - this.msg = message || ({} as IMessage); - } - - public setData(data: IMessage): IMessageBuilder { - delete data.id; - this.msg = data; - - return this; - } - - public setUpdateData(data: IMessage, editor: IUser): IMessageBuilder { - this.msg = data; - this.msg.editor = editor; - this.msg.editedAt = new Date(); - - return this; - } - - public setThreadId(threadId: string): IMessageBuilder { - this.msg.threadId = threadId; - - return this; - } - - public getThreadId(): string { - return this.msg.threadId!; - } - - public setRoom(room: IRoom): IMessageBuilder { - this.msg.room = room; - return this; - } - - public getRoom(): IRoom { - return this.msg.room!; - } - - public setSender(sender: IUser): IMessageBuilder { - this.msg.sender = sender; - return this; - } - - public getSender(): IUser { - return this.msg.sender!; - } - - public setText(text: string): IMessageBuilder { - this.msg.text = text; - return this; - } - - public getText(): string { - return this.msg.text!; - } - - public setEmojiAvatar(emoji: string): IMessageBuilder { - this.msg.emoji = emoji; - return this; - } - - public getEmojiAvatar(): string { - return this.msg.emoji!; - } - - public setAvatarUrl(avatarUrl: string): IMessageBuilder { - this.msg.avatarUrl = avatarUrl; - return this; - } - - public getAvatarUrl(): string { - return this.msg.avatarUrl!; - } - - public setUsernameAlias(alias: string): IMessageBuilder { - this.msg.alias = alias; - return this; - } - - public getUsernameAlias(): string { - return this.msg.alias!; - } - - public addAttachment(attachment: IMessageAttachment): IMessageBuilder { - if (!this.msg.attachments) { - this.msg.attachments = []; - } - - this.msg.attachments.push(attachment); - return this; - } - - public setAttachments(attachments: Array): IMessageBuilder { - this.msg.attachments = attachments; - return this; - } - - public getAttachments(): Array { - return this.msg.attachments!; - } - - public replaceAttachment(position: number, attachment: IMessageAttachment): IMessageBuilder { - if (!this.msg.attachments) { - this.msg.attachments = []; - } - - if (!this.msg.attachments[position]) { - throw new Error(`No attachment found at the index of "${position}" to replace.`); - } - - this.msg.attachments[position] = attachment; - return this; - } - - public removeAttachment(position: number): IMessageBuilder { - if (!this.msg.attachments) { - this.msg.attachments = []; - } - - if (!this.msg.attachments[position]) { - throw new Error(`No attachment found at the index of "${position}" to remove.`); - } - - this.msg.attachments.splice(position, 1); - - return this; - } - - public setEditor(user: IUser): IMessageBuilder { - this.msg.editor = user; - return this; - } - - public getEditor(): IUser { - return this.msg.editor!; - } - - public setGroupable(groupable: boolean): IMessageBuilder { - this.msg.groupable = groupable; - return this; - } - - public getGroupable(): boolean { - return this.msg.groupable!; - } - - public setParseUrls(parseUrls: boolean): IMessageBuilder { - this.msg.parseUrls = parseUrls; - return this; - } - - public getParseUrls() { - return this.msg.parseUrls!; - } - - public getMessage(): IMessage { - if (!this.msg.room) { - throw new Error('The "room" property is required.'); - } - - return this.msg; - } - - public addBlocks(blocks: BlockBuilder | Array) { - if (!Array.isArray(this.msg.blocks)) { - this.msg.blocks = []; - } - - if (blocks instanceof BlockBuilder) { - this.msg.blocks.push(...blocks.getBlocks()); - } else { - this.msg.blocks.push(...blocks); - } - - return this; - } - - public setBlocks(blocks: BlockBuilder | Array) { - if (blocks instanceof BlockBuilder) { - this.msg.blocks = blocks.getBlocks(); - } else { - this.msg.blocks = blocks; - } - - return this; - } - - public getBlocks(): Array { - return this.msg.blocks!; - } - - public addCustomField(key: string, value: any): IMessageBuilder { - if (!this.msg.customFields) { - this.msg.customFields = {}; - } - - if (this.msg.customFields[key]) { - throw new Error(`The message already contains a custom field by the key: ${key}`); - } - - if (key.includes('.')) { - throw new Error(`The given key contains a period, which is not allowed. Key: ${key}`); - } - - this.msg.customFields[key] = value; - return this; - } -} diff --git a/packages/apps/src/server/accessors/MessageExtender.ts b/packages/apps/src/server/accessors/MessageExtender.ts deleted file mode 100644 index fee05802d0856..0000000000000 --- a/packages/apps/src/server/accessors/MessageExtender.ts +++ /dev/null @@ -1,51 +0,0 @@ -import type { IMessageExtender } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IMessage, IMessageAttachment } from '@rocket.chat/apps-engine/definition/messages'; -import { RocketChatAssociationModel } from '@rocket.chat/apps-engine/definition/metadata'; - -import { Utilities } from '../misc/Utilities'; - -export class MessageExtender implements IMessageExtender { - public readonly kind: RocketChatAssociationModel.MESSAGE; - - constructor(private msg: IMessage) { - this.kind = RocketChatAssociationModel.MESSAGE; - - if (!Array.isArray(msg.attachments)) { - this.msg.attachments = []; - } - } - - public addCustomField(key: string, value: any): IMessageExtender { - if (!this.msg.customFields) { - this.msg.customFields = {}; - } - - if (this.msg.customFields[key]) { - throw new Error(`The message already contains a custom field by the key: ${key}`); - } - - if (key.includes('.')) { - throw new Error(`The given key contains a period, which is not allowed. Key: ${key}`); - } - - this.msg.customFields[key] = value; - - return this; - } - - public addAttachment(attachment: IMessageAttachment): IMessageExtender { - this.msg.attachments.push(attachment); - - return this; - } - - public addAttachments(attachments: Array): IMessageExtender { - this.msg.attachments = this.msg.attachments.concat(attachments); - - return this; - } - - public getMessage(): IMessage { - return Utilities.deepClone(this.msg); - } -} diff --git a/packages/apps/src/server/accessors/MessageRead.ts b/packages/apps/src/server/accessors/MessageRead.ts deleted file mode 100644 index 914529d07f000..0000000000000 --- a/packages/apps/src/server/accessors/MessageRead.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { IMessageRead } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IMessage } from '@rocket.chat/apps-engine/definition/messages'; -import type { IRoom } from '@rocket.chat/apps-engine/definition/rooms'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import type { MessageBridge } from '../bridges/MessageBridge'; - -export class MessageRead implements IMessageRead { - constructor( - private messageBridge: MessageBridge, - private appId: string, - ) {} - - public getById(id: string): Promise { - return this.messageBridge.doGetById(id, this.appId); - } - - public async getSenderUser(messageId: string): Promise { - const msg = await this.messageBridge.doGetById(messageId, this.appId); - - if (!msg) { - return undefined; - } - - return msg.sender; - } - - public async getRoom(messageId: string): Promise { - const msg = await this.messageBridge.doGetById(messageId, this.appId); - - if (!msg) { - return undefined; - } - - return msg.room; - } -} diff --git a/packages/apps/src/server/accessors/MessageUpdater.ts b/packages/apps/src/server/accessors/MessageUpdater.ts deleted file mode 100644 index 33728a8b833e6..0000000000000 --- a/packages/apps/src/server/accessors/MessageUpdater.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { IMessageUpdater } from '@rocket.chat/apps-engine/definition/accessors/IMessageUpdater'; -import type { Reaction } from '@rocket.chat/apps-engine/definition/messages'; - -import type { AppBridges } from '../bridges'; - -export class MessageUpdater implements IMessageUpdater { - constructor( - private readonly bridges: AppBridges, - private readonly appId: string, - ) {} - - public async addReaction(messageId: string, userId: string, reaction: Reaction): Promise { - return this.bridges.getMessageBridge().doAddReaction(messageId, userId, reaction, this.appId); - } - - public async removeReaction(messageId: string, userId: string, reaction: Reaction): Promise { - return this.bridges.getMessageBridge().doRemoveReaction(messageId, userId, reaction, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/ModerationModify.ts b/packages/apps/src/server/accessors/ModerationModify.ts deleted file mode 100644 index e74772efbac22..0000000000000 --- a/packages/apps/src/server/accessors/ModerationModify.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { IModerationModify } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IMessage } from '@rocket.chat/apps-engine/definition/messages'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import type { ModerationBridge } from '../bridges'; - -export class ModerationModify implements IModerationModify { - constructor( - private moderationBridge: ModerationBridge, - _appId: string, - ) {} - - public report(messageId: string, description: string, userId: string, appId: string): Promise { - return this.moderationBridge.doReport(messageId, description, userId, appId); - } - - public dismissReportsByMessageId(messageId: IMessage['id'], reason: string, action: string, appId: string): Promise { - return this.moderationBridge.doDismissReportsByMessageId(messageId, reason, action, appId); - } - - public dismissReportsByUserId(userId: IUser['id'], reason: string, action: string, appId: string): Promise { - return this.moderationBridge.doDismissReportsByUserId(userId, reason, action, appId); - } -} diff --git a/packages/apps/src/server/accessors/Modify.ts b/packages/apps/src/server/accessors/Modify.ts deleted file mode 100644 index e982403beed47..0000000000000 --- a/packages/apps/src/server/accessors/Modify.ts +++ /dev/null @@ -1,93 +0,0 @@ -import type { - IModify, - IModifyCreator, - IModifyDeleter, - IModifyExtender, - IModifyUpdater, - INotifier, - ISchedulerModify, - IUIController, -} from '@rocket.chat/apps-engine/definition/accessors'; -import type { IOAuthAppsModify } from '@rocket.chat/apps-engine/definition/accessors/IOAuthAppsModify'; - -import type { AppBridges } from '../bridges'; -import { ModerationModify } from './ModerationModify'; -import { ModifyCreator } from './ModifyCreator'; -import { ModifyDeleter } from './ModifyDeleter'; -import { ModifyExtender } from './ModifyExtender'; -import { ModifyUpdater } from './ModifyUpdater'; -import { Notifier } from './Notifier'; -import { OAuthAppsModify } from './OAuthAppsModify'; -import { SchedulerModify } from './SchedulerModify'; -import { UIController } from './UIController'; - -export class Modify implements IModify { - private creator: IModifyCreator; - - private deleter: IModifyDeleter; - - private updater: IModifyUpdater; - - private extender: IModifyExtender; - - private notifier: INotifier; - - private uiController: IUIController; - - private scheduler: ISchedulerModify; - - private oauthApps: IOAuthAppsModify; - - private moderation: ModerationModify; - - constructor( - private readonly bridges: AppBridges, - private readonly appId: string, - ) { - this.creator = new ModifyCreator(this.bridges, this.appId); - this.deleter = new ModifyDeleter(this.bridges, this.appId); - this.updater = new ModifyUpdater(this.bridges, this.appId); - this.extender = new ModifyExtender(this.bridges, this.appId); - this.notifier = new Notifier(this.bridges.getUserBridge(), this.bridges.getMessageBridge(), this.appId); - this.uiController = new UIController(this.appId, this.bridges); - this.scheduler = new SchedulerModify(this.bridges.getSchedulerBridge(), this.appId); - this.oauthApps = new OAuthAppsModify(this.bridges.getOAuthAppsBridge(), this.appId); - this.moderation = new ModerationModify(this.bridges.getModerationBridge(), this.appId); - } - - public getCreator(): IModifyCreator { - return this.creator; - } - - public getDeleter(): IModifyDeleter { - return this.deleter; - } - - public getUpdater(): IModifyUpdater { - return this.updater; - } - - public getExtender(): IModifyExtender { - return this.extender; - } - - public getNotifier(): INotifier { - return this.notifier; - } - - public getUiController(): IUIController { - return this.uiController; - } - - public getScheduler(): ISchedulerModify { - return this.scheduler; - } - - public getOAuthAppsModifier() { - return this.oauthApps; - } - - public getModerationModifier() { - return this.moderation; - } -} diff --git a/packages/apps/src/server/accessors/ModifyCreator.ts b/packages/apps/src/server/accessors/ModifyCreator.ts deleted file mode 100644 index 6971680ed4198..0000000000000 --- a/packages/apps/src/server/accessors/ModifyCreator.ts +++ /dev/null @@ -1,275 +0,0 @@ -import type { - IDiscussionBuilder, - ILivechatCreator, - ILivechatMessageBuilder, - IMessageBuilder, - IModifyCreator, - IRoomBuilder, - IUploadCreator, - IUserBuilder, - IVideoConferenceBuilder, -} from '@rocket.chat/apps-engine/definition/accessors'; -import type { IContactCreator } from '@rocket.chat/apps-engine/definition/accessors/IContactCreator'; -import type { IEmailCreator } from '@rocket.chat/apps-engine/definition/accessors/IEmailCreator'; -import type { ILivechatMessage } from '@rocket.chat/apps-engine/definition/livechat/ILivechatMessage'; -import type { IMessage } from '@rocket.chat/apps-engine/definition/messages'; -import { RocketChatAssociationModel } from '@rocket.chat/apps-engine/definition/metadata'; -import type { IRoom } from '@rocket.chat/apps-engine/definition/rooms'; -import { RoomType } from '@rocket.chat/apps-engine/definition/rooms'; -import { BlockBuilder } from '@rocket.chat/apps-engine/definition/uikit'; -import type { IBotUser } from '@rocket.chat/apps-engine/definition/users/IBotUser'; -import { UserType } from '@rocket.chat/apps-engine/definition/users/UserType'; -import type { AppVideoConference } from '@rocket.chat/apps-engine/definition/videoConferences'; - -import { ContactCreator } from './ContactCreator'; -import { DiscussionBuilder } from './DiscussionBuilder'; -import { EmailCreator } from './EmailCreator'; -import { LivechatCreator } from './LivechatCreator'; -import { LivechatMessageBuilder } from './LivechatMessageBuilder'; -import { MessageBuilder } from './MessageBuilder'; -import { RoomBuilder } from './RoomBuilder'; -import { UploadCreator } from './UploadCreator'; -import { UserBuilder } from './UserBuilder'; -import { VideoConferenceBuilder } from './VideoConferenceBuilder'; -import type { AppBridges } from '../bridges'; -import { UIHelper } from '../misc/UIHelper'; - -export class ModifyCreator implements IModifyCreator { - private livechatCreator: LivechatCreator; - - private uploadCreator: UploadCreator; - - private emailCreator: EmailCreator; - - private contactCreator: ContactCreator; - - constructor( - private readonly bridges: AppBridges, - private readonly appId: string, - ) { - this.livechatCreator = new LivechatCreator(bridges, appId); - this.uploadCreator = new UploadCreator(bridges, appId); - this.emailCreator = new EmailCreator(bridges, appId); - this.contactCreator = new ContactCreator(bridges, appId); - } - - public getLivechatCreator(): ILivechatCreator { - return this.livechatCreator; - } - - public getUploadCreator(): IUploadCreator { - return this.uploadCreator; - } - - public getEmailCreator(): IEmailCreator { - return this.emailCreator; - } - - public getContactCreator(): IContactCreator { - return this.contactCreator; - } - - /** - * @deprecated please prefer the rocket.chat/ui-kit components - */ - public getBlockBuilder(): BlockBuilder { - return new BlockBuilder(this.appId); - } - - public startMessage(data?: IMessage): IMessageBuilder { - if (data) { - delete data.id; - } - - return new MessageBuilder(data); - } - - public startLivechatMessage(data?: ILivechatMessage): ILivechatMessageBuilder { - if (data) { - delete data.id; - } - - return new LivechatMessageBuilder(data); - } - - public startRoom(data?: IRoom): IRoomBuilder { - if (data) { - delete data.id; - } - - return new RoomBuilder(data); - } - - public startDiscussion(data?: Partial): IDiscussionBuilder { - if (data) { - delete data.id; - } - - return new DiscussionBuilder(data); - } - - public startVideoConference(data?: Partial): IVideoConferenceBuilder { - return new VideoConferenceBuilder(data); - } - - public startBotUser(data?: Partial): IUserBuilder { - if (data) { - delete data.id; - - const { roles } = data; - - if (roles?.length) { - const hasRole = roles - .map((role) => role.toLocaleLowerCase()) - .some((role) => role === 'admin' || role === 'owner' || role === 'moderator'); - - if (hasRole) { - throw new Error('Invalid role assigned to the user. Should not be admin, owner or moderator.'); - } - } - - if (!data.type) { - data.type = UserType.BOT; - } - } - - return new UserBuilder(data); - } - - public finish( - builder: IMessageBuilder | ILivechatMessageBuilder | IRoomBuilder | IDiscussionBuilder | IVideoConferenceBuilder | IUserBuilder, - ): Promise { - switch (builder.kind) { - case RocketChatAssociationModel.MESSAGE: - return this._finishMessage(builder); - case RocketChatAssociationModel.LIVECHAT_MESSAGE: - return this._finishLivechatMessage(builder); - case RocketChatAssociationModel.ROOM: - return this._finishRoom(builder); - case RocketChatAssociationModel.DISCUSSION: - return this._finishDiscussion(builder as IDiscussionBuilder); - case RocketChatAssociationModel.VIDEO_CONFERENCE: - return this._finishVideoConference(builder); - case RocketChatAssociationModel.USER: - return this._finishUser(builder); - default: - throw new Error('Invalid builder passed to the ModifyCreator.finish function.'); - } - } - - private async _finishMessage(builder: IMessageBuilder): Promise { - const result = builder.getMessage(); - delete result.id; - - if (!result.sender?.id) { - const appUser = await this.bridges.getUserBridge().doGetAppUser(this.appId); - - if (!appUser) { - throw new Error('Invalid sender assigned to the message.'); - } - - result.sender = appUser; - } - - if (result.blocks?.length) { - result.blocks = UIHelper.assignIds(result.blocks, this.appId); - } - - return this.bridges.getMessageBridge().doCreate(result, this.appId); - } - - private _finishLivechatMessage(builder: ILivechatMessageBuilder): Promise { - if (builder.getSender() && !builder.getVisitor()) { - return this._finishMessage(builder.getMessageBuilder()); - } - - const result = builder.getMessage(); - delete result.id; - - if (!result.token && !result.visitor?.token) { - throw new Error('Invalid visitor sending the message'); - } - - result.token = result.visitor ? result.visitor.token : result.token; - - return this.bridges.getLivechatBridge().doCreateMessage(result, this.appId); - } - - private _finishRoom(builder: IRoomBuilder): Promise { - const result = builder.getRoom(); - delete result.id; - - if (!result.type) { - throw new Error('Invalid type assigned to the room.'); - } - - if (result.type !== RoomType.LIVE_CHAT) { - if (!result.creator?.id) { - throw new Error('Invalid creator assigned to the room.'); - } - } - - if (result.type !== RoomType.DIRECT_MESSAGE) { - if (result.type !== RoomType.LIVE_CHAT) { - if (!result.slugifiedName?.trim()) { - throw new Error('Invalid slugifiedName assigned to the room.'); - } - } - - if (!result.displayName?.trim()) { - throw new Error('Invalid displayName assigned to the room.'); - } - } - - return this.bridges.getRoomBridge().doCreate(result, builder.getMembersToBeAddedUsernames(), this.appId); - } - - private _finishDiscussion(builder: IDiscussionBuilder): Promise { - const room = builder.getRoom(); - delete room.id; - - if (!room.creator?.id) { - throw new Error('Invalid creator assigned to the discussion.'); - } - - if (!room.slugifiedName?.trim()) { - throw new Error('Invalid slugifiedName assigned to the discussion.'); - } - - if (!room.displayName?.trim()) { - throw new Error('Invalid displayName assigned to the discussion.'); - } - - if (!room.parentRoom?.id) { - throw new Error('Invalid parentRoom assigned to the discussion.'); - } - - return this.bridges - .getRoomBridge() - .doCreateDiscussion(room, builder.getParentMessage(), builder.getReply(), builder.getMembersToBeAddedUsernames(), this.appId); - } - - private _finishVideoConference(builder: IVideoConferenceBuilder): Promise { - const videoConference = builder.getVideoConference(); - - if (!videoConference.createdBy) { - throw new Error('Invalid creator assigned to the video conference.'); - } - - if (!videoConference.providerName?.trim()) { - throw new Error('Invalid provider name assigned to the video conference.'); - } - - if (!videoConference.rid) { - throw new Error('Invalid roomId assigned to the video conference.'); - } - - return this.bridges.getVideoConferenceBridge().doCreate(videoConference, this.appId); - } - - private _finishUser(builder: IUserBuilder): Promise { - const user = builder.getUser(); - - return this.bridges.getUserBridge().doCreate(user, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/ModifyDeleter.ts b/packages/apps/src/server/accessors/ModifyDeleter.ts deleted file mode 100644 index 50c390f2d555d..0000000000000 --- a/packages/apps/src/server/accessors/ModifyDeleter.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { IModifyDeleter } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IMessage } from '@rocket.chat/apps-engine/definition/messages'; -import type { IUser, UserType } from '@rocket.chat/apps-engine/definition/users'; - -import type { AppBridges } from '../bridges'; - -export class ModifyDeleter implements IModifyDeleter { - constructor( - private readonly bridges: AppBridges, - private readonly appId: string, - ) {} - - public async deleteRoom(roomId: string): Promise { - return this.bridges.getRoomBridge().doDelete(roomId, this.appId); - } - - public async deleteUsers(appId: Exclude, userType: UserType.APP | UserType.BOT): Promise { - return this.bridges.getUserBridge().doDeleteUsersCreatedByApp(appId, userType); - } - - public async deleteMessage(message: IMessage, user: IUser): Promise { - return this.bridges.getMessageBridge().doDelete(message, user, this.appId); - } - - /** - * Removes `usernames` from the room's member list - * - * For performance reasons, it is only possible to remove 50 users in one - * call to this method. Removing users is an expensive operation due to the - * amount of entity relationships that need to be modified. - */ - public async removeUsersFromRoom(roomId: string, usernames: Array) { - if (usernames.length > 50) { - throw new Error('A maximum of 50 members can be removed in a single call'); - } - - return this.bridges.getRoomBridge().doRemoveUsers(roomId, usernames, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/ModifyExtender.ts b/packages/apps/src/server/accessors/ModifyExtender.ts deleted file mode 100644 index 98f8dec4d0361..0000000000000 --- a/packages/apps/src/server/accessors/ModifyExtender.ts +++ /dev/null @@ -1,55 +0,0 @@ -import type { - IMessageExtender, - IModifyExtender, - IRoomExtender, - IVideoConferenceExtender, -} from '@rocket.chat/apps-engine/definition/accessors'; -import { RocketChatAssociationModel } from '@rocket.chat/apps-engine/definition/metadata'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import { MessageExtender } from './MessageExtender'; -import { RoomExtender } from './RoomExtender'; -import { VideoConferenceExtender } from './VideoConferenceExtend'; -import type { AppBridges } from '../bridges/AppBridges'; - -export class ModifyExtender implements IModifyExtender { - constructor( - private readonly bridges: AppBridges, - private readonly appId: string, - ) {} - - public async extendMessage(messageId: string, updater: IUser): Promise { - const msg = await this.bridges.getMessageBridge().doGetById(messageId, this.appId); - msg.editor = updater; - msg.editedAt = new Date(); - - return new MessageExtender(msg); - } - - public async extendRoom(roomId: string, _updater: IUser): Promise { - const room = await this.bridges.getRoomBridge().doGetById(roomId, this.appId); - room.updatedAt = new Date(); - - return new RoomExtender(room); - } - - public async extendVideoConference(id: string): Promise { - const call = await this.bridges.getVideoConferenceBridge().doGetById(id, this.appId); - call._updatedAt = new Date(); - - return new VideoConferenceExtender(call); - } - - public finish(extender: IMessageExtender | IRoomExtender | IVideoConferenceExtender): Promise { - switch (extender.kind) { - case RocketChatAssociationModel.MESSAGE: - return this.bridges.getMessageBridge().doUpdate(extender.getMessage(), this.appId); - case RocketChatAssociationModel.ROOM: - return this.bridges.getRoomBridge().doUpdate(extender.getRoom(), extender.getUsernamesOfMembersBeingAdded(), this.appId); - case RocketChatAssociationModel.VIDEO_CONFERENCE: - return this.bridges.getVideoConferenceBridge().doUpdate(extender.getVideoConference(), this.appId); - default: - throw new Error('Invalid extender passed to the ModifyExtender.finish function.'); - } - } -} diff --git a/packages/apps/src/server/accessors/ModifyUpdater.ts b/packages/apps/src/server/accessors/ModifyUpdater.ts deleted file mode 100644 index 1da37395ef696..0000000000000 --- a/packages/apps/src/server/accessors/ModifyUpdater.ts +++ /dev/null @@ -1,118 +0,0 @@ -import type { - ILivechatUpdater, - IMessageBuilder, - IMessageUpdater, - IModifyUpdater, - IRoomBuilder, -} from '@rocket.chat/apps-engine/definition/accessors'; -import type { IUserUpdater } from '@rocket.chat/apps-engine/definition/accessors/IUserUpdater'; -import { RocketChatAssociationModel } from '@rocket.chat/apps-engine/definition/metadata'; -import { RoomType } from '@rocket.chat/apps-engine/definition/rooms'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import { LivechatUpdater } from './LivechatUpdater'; -import { MessageBuilder } from './MessageBuilder'; -import { MessageUpdater } from './MessageUpdater'; -import { RoomBuilder } from './RoomBuilder'; -import { UserUpdater } from './UserUpdater'; -import type { AppBridges } from '../bridges'; -import { UIHelper } from '../misc/UIHelper'; - -export class ModifyUpdater implements IModifyUpdater { - private livechatUpdater: ILivechatUpdater; - - private userUpdater: IUserUpdater; - - private messageUpdater: IMessageUpdater; - - constructor( - private readonly bridges: AppBridges, - private readonly appId: string, - ) { - this.livechatUpdater = new LivechatUpdater(this.bridges, this.appId); - this.userUpdater = new UserUpdater(this.bridges, this.appId); - this.messageUpdater = new MessageUpdater(this.bridges, this.appId); - } - - public getLivechatUpdater(): ILivechatUpdater { - return this.livechatUpdater; - } - - public getUserUpdater(): IUserUpdater { - return this.userUpdater; - } - - public getMessageUpdater(): IMessageUpdater { - return this.messageUpdater; - } - - public async message(messageId: string, _updater: IUser): Promise { - const msg = await this.bridges.getMessageBridge().doGetById(messageId, this.appId); - - return new MessageBuilder(msg); - } - - public async room(roomId: string, _updater: IUser): Promise { - const room = await this.bridges.getRoomBridge().doGetById(roomId, this.appId); - - return new RoomBuilder(room); - } - - public finish(builder: IMessageBuilder | IRoomBuilder): Promise { - switch (builder.kind) { - case RocketChatAssociationModel.MESSAGE: - return this._finishMessage(builder); - case RocketChatAssociationModel.ROOM: - return this._finishRoom(builder); - default: - throw new Error('Invalid builder passed to the ModifyUpdater.finish function.'); - } - } - - private _finishMessage(builder: IMessageBuilder): Promise { - const result = builder.getMessage(); - - if (!result.id) { - throw new Error("Invalid message, can't update a message without an id."); - } - - if (!result.sender?.id) { - throw new Error('Invalid sender assigned to the message.'); - } - - if (result.blocks?.length) { - result.blocks = UIHelper.assignIds(result.blocks, this.appId); - // result.blocks = this._assignIds(result.blocks); - } - - return this.bridges.getMessageBridge().doUpdate(result, this.appId); - } - - private _finishRoom(builder: IRoomBuilder): Promise { - const result = builder.getRoom(); - - if (!result.id) { - throw new Error('Invalid room, can not update a room without an id.'); - } - - if (!result.type) { - throw new Error('Invalid type assigned to the room.'); - } - - if (result.type !== RoomType.LIVE_CHAT) { - if (!result.creator?.id) { - throw new Error('Invalid creator assigned to the room.'); - } - - if (!result.slugifiedName?.trim()) { - throw new Error('Invalid slugifiedName assigned to the room.'); - } - } - - if (!result.displayName?.trim()) { - throw new Error('Invalid displayName assigned to the room.'); - } - - return this.bridges.getRoomBridge().doUpdate(result, builder.getMembersToBeAddedUsernames(), this.appId); - } -} diff --git a/packages/apps/src/server/accessors/Notifier.ts b/packages/apps/src/server/accessors/Notifier.ts deleted file mode 100644 index ba5b46b841717..0000000000000 --- a/packages/apps/src/server/accessors/Notifier.ts +++ /dev/null @@ -1,54 +0,0 @@ -import type { IMessageBuilder, INotifier } from '@rocket.chat/apps-engine/definition/accessors'; -import type { ITypingOptions } from '@rocket.chat/apps-engine/definition/accessors/INotifier'; -import { TypingScope } from '@rocket.chat/apps-engine/definition/accessors/INotifier'; -import type { IMessage } from '@rocket.chat/apps-engine/definition/messages'; -import type { IRoom } from '@rocket.chat/apps-engine/definition/rooms'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import type { MessageBridge, UserBridge } from '../bridges'; -import { MessageBuilder } from './MessageBuilder'; - -export class Notifier implements INotifier { - constructor( - private readonly userBridge: UserBridge, - private readonly msgBridge: MessageBridge, - private readonly appId: string, - ) {} - - public async notifyUser(user: IUser, message: IMessage): Promise { - if (!message.sender?.id) { - const appUser = (await this.userBridge.doGetAppUser(this.appId)) as IUser; - - message.sender = appUser; - } - - await this.msgBridge.doNotifyUser(user, message, this.appId); - } - - public async notifyRoom(room: IRoom, message: IMessage): Promise { - if (!message.sender?.id) { - const appUser = (await this.userBridge.doGetAppUser(this.appId)) as IUser; - - message.sender = appUser; - } - - await this.msgBridge.doNotifyRoom(room, message, this.appId); - } - - public async typing(options: ITypingOptions): Promise<() => Promise> { - options.scope = options.scope || TypingScope.Room; - - if (!options.username) { - const appUser = await this.userBridge.doGetAppUser(this.appId); - options.username = appUser?.name || ''; - } - - void this.msgBridge.doTyping({ ...options, isTyping: true }, this.appId); - - return () => this.msgBridge.doTyping({ ...options, isTyping: false }, this.appId); - } - - public getMessageBuilder(): IMessageBuilder { - return new MessageBuilder(); - } -} diff --git a/packages/apps/src/server/accessors/OAuthAppsModify.ts b/packages/apps/src/server/accessors/OAuthAppsModify.ts deleted file mode 100644 index 2946504f5b08e..0000000000000 --- a/packages/apps/src/server/accessors/OAuthAppsModify.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { IOAuthAppParams } from '@rocket.chat/apps-engine/definition/accessors/IOAuthApp'; -import type { IOAuthAppsModify } from '@rocket.chat/apps-engine/definition/accessors/IOAuthAppsModify'; - -import type { OAuthAppsBridge } from '../bridges/OAuthAppsBridge'; - -export class OAuthAppsModify implements IOAuthAppsModify { - constructor( - private readonly oauthAppsBridge: OAuthAppsBridge, - private readonly appId: string, - ) {} - - public async createOAuthApp(oAuthApp: IOAuthAppParams): Promise { - return this.oauthAppsBridge.doCreate(oAuthApp, this.appId); - } - - public async updateOAuthApp(oAuthApp: IOAuthAppParams, id: string): Promise { - return this.oauthAppsBridge.doUpdate(oAuthApp, id, this.appId); - } - - public async deleteOAuthApp(id: string): Promise { - return this.oauthAppsBridge.doDelete(id, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/OAuthAppsReader.ts b/packages/apps/src/server/accessors/OAuthAppsReader.ts deleted file mode 100644 index 6de492e00a64e..0000000000000 --- a/packages/apps/src/server/accessors/OAuthAppsReader.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { IOAuthApp } from '@rocket.chat/apps-engine/definition/accessors/IOAuthApp'; -import type { IOAuthAppsReader } from '@rocket.chat/apps-engine/definition/accessors/IOAuthAppsReader'; - -import type { OAuthAppsBridge } from '../bridges/OAuthAppsBridge'; - -export class OAuthAppsReader implements IOAuthAppsReader { - constructor( - private readonly oauthAppsBridge: OAuthAppsBridge, - private readonly appId: string, - ) {} - - public async getOAuthAppById(id: string): Promise { - return this.oauthAppsBridge.doGetByid(id, this.appId); - } - - public async getOAuthAppByName(name: string): Promise> { - return this.oauthAppsBridge.doGetByName(name, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/OutboundCommunicationProviderExtend.ts b/packages/apps/src/server/accessors/OutboundCommunicationProviderExtend.ts deleted file mode 100644 index d1ba5b7fdc514..0000000000000 --- a/packages/apps/src/server/accessors/OutboundCommunicationProviderExtend.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { IOutboundCommunicationProviderExtend } from '@rocket.chat/apps-engine/definition/accessors/IOutboundCommunicationProviderExtend'; -import type { - IOutboundPhoneMessageProvider, - IOutboundEmailMessageProvider, -} from '@rocket.chat/apps-engine/definition/outboundCommunication'; - -import type { AppOutboundCommunicationProviderManager } from '../managers/AppOutboundCommunicationProviderManager'; - -export class OutboundMessageProviderExtend implements IOutboundCommunicationProviderExtend { - constructor( - private readonly manager: AppOutboundCommunicationProviderManager, - private readonly appId: string, - ) {} - - public registerPhoneProvider(provider: IOutboundPhoneMessageProvider): Promise { - return Promise.resolve(this.manager.addProvider(this.appId, provider)); - } - - public registerEmailProvider(provider: IOutboundEmailMessageProvider): Promise { - return Promise.resolve(this.manager.addProvider(this.appId, provider)); - } -} diff --git a/packages/apps/src/server/accessors/Persistence.ts b/packages/apps/src/server/accessors/Persistence.ts deleted file mode 100644 index 6cff70718069e..0000000000000 --- a/packages/apps/src/server/accessors/Persistence.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { IPersistence } from '@rocket.chat/apps-engine/definition/accessors'; -import type { RocketChatAssociationRecord } from '@rocket.chat/apps-engine/definition/metadata'; - -import type { PersistenceBridge } from '../bridges/PersistenceBridge'; - -export class Persistence implements IPersistence { - constructor( - private persistBridge: PersistenceBridge, - private appId: string, - ) {} - - public create(data: object): Promise { - return this.persistBridge.doCreate(data, this.appId); - } - - public createWithAssociation(data: object, association: RocketChatAssociationRecord): Promise { - return this.persistBridge.doCreateWithAssociations(data, new Array(association), this.appId); - } - - public createWithAssociations(data: object, associations: Array): Promise { - return this.persistBridge.doCreateWithAssociations(data, associations, this.appId); - } - - public update(id: string, data: object, upsert = false): Promise { - return this.persistBridge.doUpdate(id, data, upsert, this.appId); - } - - public updateByAssociation(association: RocketChatAssociationRecord, data: object, upsert = false): Promise { - return this.persistBridge.doUpdateByAssociations(new Array(association), data, upsert, this.appId); - } - - public updateByAssociations(associations: Array, data: object, upsert = false): Promise { - return this.persistBridge.doUpdateByAssociations(associations, data, upsert, this.appId); - } - - public remove(id: string): Promise { - return this.persistBridge.doRemove(id, this.appId); - } - - public removeByAssociation(association: RocketChatAssociationRecord): Promise> { - return this.persistBridge.doRemoveByAssociations(new Array(association), this.appId); - } - - public removeByAssociations(associations: Array): Promise> { - return this.persistBridge.doRemoveByAssociations(associations, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/PersistenceRead.ts b/packages/apps/src/server/accessors/PersistenceRead.ts deleted file mode 100644 index dc8fcddc935c4..0000000000000 --- a/packages/apps/src/server/accessors/PersistenceRead.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { IPersistenceRead } from '@rocket.chat/apps-engine/definition/accessors'; -import type { RocketChatAssociationRecord } from '@rocket.chat/apps-engine/definition/metadata'; - -import type { PersistenceBridge } from '../bridges'; - -export class PersistenceRead implements IPersistenceRead { - constructor( - private persistBridge: PersistenceBridge, - private appId: string, - ) {} - - public read(id: string): Promise { - return this.persistBridge.doReadById(id, this.appId); - } - - public readByAssociation(association: RocketChatAssociationRecord): Promise> { - return this.persistBridge.doReadByAssociations(new Array(association), this.appId); - } - - public readByAssociations(associations: Array): Promise> { - return this.persistBridge.doReadByAssociations(associations, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/Reader.ts b/packages/apps/src/server/accessors/Reader.ts deleted file mode 100644 index 2f73452b1af85..0000000000000 --- a/packages/apps/src/server/accessors/Reader.ts +++ /dev/null @@ -1,98 +0,0 @@ -import type { - ICloudWorkspaceRead, - IEnvironmentRead, - IExperimentalRead, - ILivechatRead, - IMessageRead, - INotifier, - IPersistenceRead, - IRead, - IRoomRead, - IUploadRead, - IUserRead, - IVideoConferenceRead, -} from '@rocket.chat/apps-engine/definition/accessors'; -import type { IContactRead } from '@rocket.chat/apps-engine/definition/accessors/IContactRead'; -import type { IOAuthAppsReader } from '@rocket.chat/apps-engine/definition/accessors/IOAuthAppsReader'; -import type { IRoleRead } from '@rocket.chat/apps-engine/definition/accessors/IRoleRead'; -import type { IThreadRead } from '@rocket.chat/apps-engine/definition/accessors/IThreadRead'; - -export class Reader implements IRead { - constructor( - private env: IEnvironmentRead, - private message: IMessageRead, - private persist: IPersistenceRead, - private room: IRoomRead, - private user: IUserRead, - private noti: INotifier, - private livechat: ILivechatRead, - private upload: IUploadRead, - private cloud: ICloudWorkspaceRead, - private videoConf: IVideoConferenceRead, - private contactRead: IContactRead, - private oauthApps: IOAuthAppsReader, - private thread: IThreadRead, - private role: IRoleRead, - private experimental: IExperimentalRead, - ) {} - - public getEnvironmentReader(): IEnvironmentRead { - return this.env; - } - - public getThreadReader(): IThreadRead { - return this.thread; - } - - public getMessageReader(): IMessageRead { - return this.message; - } - - public getPersistenceReader(): IPersistenceRead { - return this.persist; - } - - public getRoomReader(): IRoomRead { - return this.room; - } - - public getUserReader(): IUserRead { - return this.user; - } - - public getNotifier(): INotifier { - return this.noti; - } - - public getLivechatReader(): ILivechatRead { - return this.livechat; - } - - public getUploadReader(): IUploadRead { - return this.upload; - } - - public getCloudWorkspaceReader(): ICloudWorkspaceRead { - return this.cloud; - } - - public getVideoConferenceReader(): IVideoConferenceRead { - return this.videoConf; - } - - public getOAuthAppsReader(): IOAuthAppsReader { - return this.oauthApps; - } - - public getRoleReader(): IRoleRead { - return this.role; - } - - public getContactReader(): IContactRead { - return this.contactRead; - } - - public getExperimentalReader(): IExperimentalRead { - return this.experimental; - } -} diff --git a/packages/apps/src/server/accessors/RoleRead.ts b/packages/apps/src/server/accessors/RoleRead.ts deleted file mode 100644 index a6ad18742aea5..0000000000000 --- a/packages/apps/src/server/accessors/RoleRead.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { IRoleRead } from '@rocket.chat/apps-engine/definition/accessors/IRoleRead'; -import type { IRole } from '@rocket.chat/apps-engine/definition/roles'; - -import type { RoleBridge } from '../bridges'; - -export class RoleRead implements IRoleRead { - constructor( - private roleBridge: RoleBridge, - private appId: string, - ) {} - - public getOneByIdOrName(idOrName: string): Promise { - return this.roleBridge.doGetOneByIdOrName(idOrName, this.appId); - } - - public getCustomRoles(): Promise> { - return this.roleBridge.doGetCustomRoles(this.appId); - } -} diff --git a/packages/apps/src/server/accessors/RoomBuilder.ts b/packages/apps/src/server/accessors/RoomBuilder.ts deleted file mode 100644 index aa1e4c31d43b7..0000000000000 --- a/packages/apps/src/server/accessors/RoomBuilder.ts +++ /dev/null @@ -1,155 +0,0 @@ -import type { IRoomBuilder } from '@rocket.chat/apps-engine/definition/accessors'; -import { RocketChatAssociationModel } from '@rocket.chat/apps-engine/definition/metadata'; -import type { IRoom, RoomType } from '@rocket.chat/apps-engine/definition/rooms'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -export class RoomBuilder implements IRoomBuilder { - public kind: RocketChatAssociationModel.ROOM | RocketChatAssociationModel.DISCUSSION; - - protected room: IRoom; - - private members: Array; - - constructor(data?: Partial) { - this.kind = RocketChatAssociationModel.ROOM; - this.room = (data || { customFields: {} }) as IRoom; - this.members = []; - } - - public setData(data: Partial): IRoomBuilder { - delete data.id; - this.room = data as IRoom; - - return this; - } - - public setDisplayName(name: string): IRoomBuilder { - this.room.displayName = name; - return this; - } - - public getDisplayName(): string { - return this.room.displayName; - } - - public setSlugifiedName(name: string): IRoomBuilder { - this.room.slugifiedName = name; - return this; - } - - public getSlugifiedName(): string { - return this.room.slugifiedName; - } - - public setType(type: RoomType): IRoomBuilder { - this.room.type = type; - return this; - } - - public getType(): RoomType { - return this.room.type; - } - - public setCreator(creator: IUser): IRoomBuilder { - this.room.creator = creator; - return this; - } - - public getCreator(): IUser { - return this.room.creator; - } - - /** - * @deprecated - */ - public addUsername(username: string): IRoomBuilder { - this.addMemberToBeAddedByUsername(username); - return this; - } - - /** - * @deprecated - */ - public setUsernames(usernames: Array): IRoomBuilder { - this.setMembersToBeAddedByUsernames(usernames); - return this; - } - - /** - * @deprecated - */ - public getUsernames(): Array { - const usernames = this.getMembersToBeAddedUsernames(); - if (usernames && usernames.length > 0) { - return usernames; - } - return this.room.usernames || []; - } - - public addMemberToBeAddedByUsername(username: string): IRoomBuilder { - this.members.push(username); - return this; - } - - public setMembersToBeAddedByUsernames(usernames: Array): IRoomBuilder { - this.members = usernames; - return this; - } - - public getMembersToBeAddedUsernames(): Array { - return this.members; - } - - public setDefault(isDefault: boolean): IRoomBuilder { - this.room.isDefault = isDefault; - return this; - } - - public getIsDefault(): boolean { - return this.room.isDefault; - } - - public setReadOnly(isReadOnly: boolean): IRoomBuilder { - this.room.isReadOnly = isReadOnly; - return this; - } - - public getIsReadOnly(): boolean { - return this.room.isReadOnly; - } - - public setDisplayingOfSystemMessages(displaySystemMessages: boolean): IRoomBuilder { - this.room.displaySystemMessages = displaySystemMessages; - return this; - } - - public getDisplayingOfSystemMessages(): boolean { - return this.room.displaySystemMessages; - } - - public addCustomField(key: string, value: object): IRoomBuilder { - if (typeof this.room.customFields !== 'object') { - this.room.customFields = {}; - } - - this.room.customFields[key] = value; - return this; - } - - public setCustomFields(fields: { [key: string]: object }): IRoomBuilder { - this.room.customFields = fields; - return this; - } - - public getCustomFields(): { [key: string]: object } { - return this.room.customFields; - } - - public getUserIds(): Array { - return this.room.userIds; - } - - public getRoom(): IRoom { - return this.room; - } -} diff --git a/packages/apps/src/server/accessors/RoomExtender.ts b/packages/apps/src/server/accessors/RoomExtender.ts deleted file mode 100644 index 05722126d6791..0000000000000 --- a/packages/apps/src/server/accessors/RoomExtender.ts +++ /dev/null @@ -1,57 +0,0 @@ -import type { IRoomExtender } from '@rocket.chat/apps-engine/definition/accessors'; -import { RocketChatAssociationModel } from '@rocket.chat/apps-engine/definition/metadata'; -import type { IRoom } from '@rocket.chat/apps-engine/definition/rooms'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import { Utilities } from '../misc/Utilities'; - -export class RoomExtender implements IRoomExtender { - public kind: RocketChatAssociationModel.ROOM; - - private members: Array; - - constructor(private room: IRoom) { - this.kind = RocketChatAssociationModel.ROOM; - this.members = []; - } - - public addCustomField(key: string, value: any): IRoomExtender { - if (!this.room.customFields) { - this.room.customFields = {}; - } - - if (this.room.customFields[key]) { - throw new Error(`The room already contains a custom field by the key: ${key}`); - } - - if (key.includes('.')) { - throw new Error(`The given key contains a period, which is not allowed. Key: ${key}`); - } - - this.room.customFields[key] = value; - - return this; - } - - public addMember(user: IUser): IRoomExtender { - if (this.members.find((u) => u.username === user.username)) { - throw new Error('The user is already in the room.'); - } - - this.members.push(user); - - return this; - } - - public getMembersBeingAdded(): Array { - return this.members; - } - - public getUsernamesOfMembersBeingAdded(): Array { - return this.members.map((u) => u.username); - } - - public getRoom(): IRoom { - return Utilities.deepClone(this.room); - } -} diff --git a/packages/apps/src/server/accessors/RoomRead.ts b/packages/apps/src/server/accessors/RoomRead.ts deleted file mode 100644 index 99bf71e51e913..0000000000000 --- a/packages/apps/src/server/accessors/RoomRead.ts +++ /dev/null @@ -1,112 +0,0 @@ -import type { IRoomRead } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IMessageRaw } from '@rocket.chat/apps-engine/definition/messages'; -import type { IRoom, IRoomRaw } from '@rocket.chat/apps-engine/definition/rooms'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import type { RoomBridge } from '../bridges'; -import { type GetMessagesOptions, type GetRoomsFilters, type GetRoomsOptions, GetMessagesSortableFields } from '../bridges/RoomBridge'; - -export class RoomRead implements IRoomRead { - constructor( - private roomBridge: RoomBridge, - private appId: string, - ) {} - - public getById(id: string): Promise { - return this.roomBridge.doGetById(id, this.appId); - } - - public getCreatorUserById(id: string): Promise { - return this.roomBridge.doGetCreatorById(id, this.appId); - } - - public getByName(name: string): Promise { - return this.roomBridge.doGetByName(name, this.appId); - } - - public getCreatorUserByName(name: string): Promise { - return this.roomBridge.doGetCreatorByName(name, this.appId); - } - - public getMessages(roomId: string, options: Partial = {}): Promise { - if (typeof options.limit !== 'undefined' && (!Number.isFinite(options.limit) || options.limit > 100)) { - throw new Error(`Invalid limit provided. Expected number <= 100, got ${options.limit}`); - } - - options.limit ??= 100; - options.showThreadMessages ??= true; - - if (options.sort) { - this.validateSort(options.sort); - } - - return this.roomBridge.doGetMessages(roomId, options as GetMessagesOptions, this.appId); - } - - public getMembers(roomId: string): Promise> { - return this.roomBridge.doGetMembers(roomId, this.appId); - } - - public getAllRooms(filters: GetRoomsFilters = {}, { limit = 100, skip = 0 }: GetRoomsOptions = {}): Promise | undefined> { - if (!Number.isFinite(limit) || limit <= 0 || limit > 100) { - throw new Error(`Invalid limit provided. Expected number between 1 and 100, got ${limit}`); - } - - if (!Number.isFinite(skip) || skip < 0) { - throw new Error(`Invalid skip provided. Expected number >= 0, got ${skip}`); - } - - return this.roomBridge.doGetAllRooms(filters, { limit, skip }, this.appId); - } - - public getDirectByUsernames(usernames: Array): Promise { - return this.roomBridge.doGetDirectByUsernames(usernames, this.appId); - } - - public getModerators(roomId: string): Promise> { - return this.roomBridge.doGetModerators(roomId, this.appId); - } - - public getOwners(roomId: string): Promise> { - return this.roomBridge.doGetOwners(roomId, this.appId); - } - - public getLeaders(roomId: string): Promise> { - return this.roomBridge.doGetLeaders(roomId, this.appId); - } - - public async getUnreadByUser(roomId: string, uid: string, options: Partial = {}): Promise { - const { limit = 100, sort = { createdAt: 'asc' }, skip = 0, showThreadMessages = true } = options; - - if (typeof roomId !== 'string' || roomId.trim().length === 0) { - throw new Error('Invalid roomId: must be a non-empty string'); - } - - if (!Number.isFinite(limit) || limit <= 0 || limit > 100) { - throw new Error(`Invalid limit provided. Expected number between 1 and 100, got ${limit}`); - } - - this.validateSort(sort); - - const completeOptions: GetMessagesOptions = { limit, sort, skip, showThreadMessages }; - - return this.roomBridge.doGetUnreadByUser(roomId, uid, completeOptions, this.appId); - } - - public getUserUnreadMessageCount(roomId: string, uid: string): Promise { - return this.roomBridge.doGetUserUnreadMessageCount(roomId, uid, this.appId); - } - - // If there are any invalid fields or values, throw - private validateSort(sort: Record) { - Object.entries(sort).forEach(([key, value]) => { - if (!GetMessagesSortableFields.includes(key as (typeof GetMessagesSortableFields)[number])) { - throw new Error(`Invalid key "${key}" used in sort. Available keys for sorting are ${GetMessagesSortableFields.join(', ')}`); - } - - if (value !== 'asc' && value !== 'desc') { - throw new Error(`Invalid sort direction for field "${key}". Expected "asc" or "desc", got ${value}`); - } - }); - } -} diff --git a/packages/apps/src/server/accessors/SchedulerExtend.ts b/packages/apps/src/server/accessors/SchedulerExtend.ts deleted file mode 100644 index 753bd4aa14a1a..0000000000000 --- a/packages/apps/src/server/accessors/SchedulerExtend.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { ISchedulerExtend } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IProcessor } from '@rocket.chat/apps-engine/definition/scheduler'; - -import type { AppSchedulerManager } from '../managers/AppSchedulerManager'; - -export class SchedulerExtend implements ISchedulerExtend { - constructor( - private readonly manager: AppSchedulerManager, - private readonly appId: string, - ) {} - - public async registerProcessors(processors: Array = []): Promise> { - return this.manager.registerProcessors(processors, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/SchedulerModify.ts b/packages/apps/src/server/accessors/SchedulerModify.ts deleted file mode 100644 index 20e82909ac3eb..0000000000000 --- a/packages/apps/src/server/accessors/SchedulerModify.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { ISchedulerModify } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IOnetimeSchedule, IRecurringSchedule } from '@rocket.chat/apps-engine/definition/scheduler'; - -import type { SchedulerBridge } from '../bridges'; - -function createProcessorId(jobId: string, appId: string): string { - return jobId.includes(`_${appId}`) ? jobId : `${jobId}_${appId}`; -} - -export class SchedulerModify implements ISchedulerModify { - constructor( - private readonly bridge: SchedulerBridge, - private readonly appId: string, - ) {} - - public async scheduleOnce(job: IOnetimeSchedule): Promise { - return this.bridge.doScheduleOnce({ ...job, id: createProcessorId(job.id, this.appId) }, this.appId); - } - - public async scheduleRecurring(job: IRecurringSchedule): Promise { - return this.bridge.doScheduleRecurring({ ...job, id: createProcessorId(job.id, this.appId) }, this.appId); - } - - public async cancelJob(jobId: string): Promise { - return this.bridge.doCancelJob(createProcessorId(jobId, this.appId), this.appId); - } - - public async cancelAllJobs(): Promise { - return this.bridge.doCancelAllJobs(this.appId); - } -} diff --git a/packages/apps/src/server/accessors/ServerSettingRead.ts b/packages/apps/src/server/accessors/ServerSettingRead.ts deleted file mode 100644 index 5bfab63c4054f..0000000000000 --- a/packages/apps/src/server/accessors/ServerSettingRead.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { IServerSettingRead } from '@rocket.chat/apps-engine/definition/accessors'; -import type { ISetting } from '@rocket.chat/apps-engine/definition/settings'; - -import type { ServerSettingBridge } from '../bridges/ServerSettingBridge'; - -export class ServerSettingRead implements IServerSettingRead { - constructor( - private readonly settingBridge: ServerSettingBridge, - private readonly appId: string, - ) {} - - public getOneById(id: string): Promise { - return this.settingBridge.doGetOneById(id, this.appId); - } - - public async getValueById(id: string): Promise { - const set = await this.settingBridge.doGetOneById(id, this.appId); - - if (typeof set === 'undefined') { - throw new Error(`No Server Setting found, or it is unaccessible, by the id of "${id}".`); - } - - if (set.value === undefined || set.value === null) { - return set.packageValue; - } - - return set.value; - } - - public getAll(): Promise> { - throw new Error('Method not implemented.'); - // return this.settingBridge.getAll(this.appId); - } - - public isReadableById(id: string): Promise { - return this.settingBridge.doIsReadableById(id, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/ServerSettingUpdater.ts b/packages/apps/src/server/accessors/ServerSettingUpdater.ts deleted file mode 100644 index 280aae967a819..0000000000000 --- a/packages/apps/src/server/accessors/ServerSettingUpdater.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { IServerSettingUpdater } from '@rocket.chat/apps-engine/definition/accessors'; -import type { ISetting } from '@rocket.chat/apps-engine/definition/settings'; - -import type { AppBridges } from '../bridges'; - -export class ServerSettingUpdater implements IServerSettingUpdater { - constructor( - private readonly bridges: AppBridges, - private readonly appId: string, - ) {} - - public async updateOne(setting: ISetting): Promise { - await this.bridges.getServerSettingBridge().doUpdateOne(setting, this.appId); - } - - public async incrementValue(id: ISetting['id'], value = 1): Promise { - await this.bridges.getServerSettingBridge().doIncrementValue(id, value, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/ServerSettingsModify.ts b/packages/apps/src/server/accessors/ServerSettingsModify.ts deleted file mode 100644 index c742ffbe5bf70..0000000000000 --- a/packages/apps/src/server/accessors/ServerSettingsModify.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type { IServerSettingsModify } from '@rocket.chat/apps-engine/definition/accessors'; -import type { ISetting } from '@rocket.chat/apps-engine/definition/settings'; - -import type { ServerSettingBridge } from '../bridges/ServerSettingBridge'; - -export class ServerSettingsModify implements IServerSettingsModify { - constructor( - private readonly bridge: ServerSettingBridge, - private readonly appId: string, - ) {} - - public async hideGroup(name: string): Promise { - await this.bridge.doHideGroup(name, this.appId); - } - - public async hideSetting(id: string): Promise { - await this.bridge.doHideSetting(id, this.appId); - } - - public async modifySetting(setting: ISetting): Promise { - await this.bridge.doUpdateOne(setting, this.appId); - } - - public async incrementValue(id: ISetting['id'], value = 1): Promise { - await this.bridge.doIncrementValue(id, value, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/SettingRead.ts b/packages/apps/src/server/accessors/SettingRead.ts deleted file mode 100644 index 04d076fa7d323..0000000000000 --- a/packages/apps/src/server/accessors/SettingRead.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { ISettingRead } from '@rocket.chat/apps-engine/definition/accessors'; -import type { ISetting } from '@rocket.chat/apps-engine/definition/settings'; - -import type { ProxiedApp } from '../ProxiedApp'; - -export class SettingRead implements ISettingRead { - constructor(private readonly app: ProxiedApp) {} - - public getById(id: string): Promise { - return Promise.resolve(this.app.getStorageItem().settings[id]); - } - - public async getValueById(id: string): Promise { - const set = await this.getById(id); - - if (typeof set === 'undefined') { - throw new Error(`Setting "${id}" does not exist.`); - } - - if (set.value === undefined || set.value === null) { - return set.packageValue; - } - - return set.value; - } -} diff --git a/packages/apps/src/server/accessors/SettingUpdater.ts b/packages/apps/src/server/accessors/SettingUpdater.ts deleted file mode 100644 index 45bc4b5ecabbe..0000000000000 --- a/packages/apps/src/server/accessors/SettingUpdater.ts +++ /dev/null @@ -1,67 +0,0 @@ -import type { ISettingUpdater } from '@rocket.chat/apps-engine/definition/accessors/ISettingUpdater'; -import type { ISetting } from '@rocket.chat/apps-engine/definition/settings'; - -import type { ProxiedApp } from '../ProxiedApp'; -import type { AppSettingsManager } from '../managers'; - -/** - * Implementation of ISettingUpdater that provides methods to update app settings. - */ -export class SettingUpdater implements ISettingUpdater { - constructor( - private readonly app: ProxiedApp, - private readonly manager: AppSettingsManager, - ) {} - - /** - * Updates a single setting value - * @param id The setting ID to update - * @param value The new value to set - * @returns Promise that resolves when the update is complete - * @throws Error if the setting doesn't exist - */ - public async updateValue(id: ISetting['id'], value: ISetting['value']): Promise { - const appId = this.app.getID(); - const storageItem = this.app.getStorageItem(); - - if (!storageItem.settings?.[id]) { - throw new Error(`Setting "${id}" not found for app ${appId}`); - } - - const setting = this.manager.getAppSetting(appId, id); - - await this.manager.updateAppSetting(appId, { - ...setting, - updatedAt: new Date(), - value, - }); - } - - /** - * Updates the values for a multi-value setting by overwriting them - * @param id The setting ID to update - * @param values The new values to set - * @returns Promise that resolves when the update is complete - * @throws Error if the setting doesn't exist - */ - public async updateSelectOptions(id: ISetting['id'], values: ISetting['values']): Promise { - const appId = this.app.getID(); - const storageItem = this.app.getStorageItem(); - - if (!storageItem.settings?.[id]) { - throw new Error(`Setting "${id}" not found for app ${appId}`); - } - - const setting = this.manager.getAppSetting(appId, id); - - // TODO: This operation completely overwrites existing values - // which could lead to loss of selected values. Consider: - // Adding warning logs when selected value will be removed - - await this.manager.updateAppSetting(appId, { - ...setting, - updatedAt: new Date(), - values, // Overwrite the values instead of merging - }); - } -} diff --git a/packages/apps/src/server/accessors/SettingsExtend.ts b/packages/apps/src/server/accessors/SettingsExtend.ts deleted file mode 100644 index 951c3f4610a83..0000000000000 --- a/packages/apps/src/server/accessors/SettingsExtend.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type { ISettingsExtend } from '@rocket.chat/apps-engine/definition/accessors'; -import type { ISetting } from '@rocket.chat/apps-engine/definition/settings'; - -import type { ProxiedApp } from '../ProxiedApp'; - -export class SettingsExtend implements ISettingsExtend { - constructor(private readonly app: ProxiedApp) {} - - public async provideSetting(setting: ISetting): Promise { - if (this.app.getStorageItem().settings[setting.id]) { - // :see_no_evil: - const old = await Promise.resolve(this.app.getStorageItem().settings[setting.id]); - - setting.createdAt = old.createdAt; - setting.updatedAt = new Date(); - setting.value = old.value; - - this.app.getStorageItem().settings[setting.id] = setting; - - return; - } - - setting.createdAt = new Date(); - setting.updatedAt = new Date(); - this.app.getStorageItem().settings[setting.id] = setting; - } -} diff --git a/packages/apps/src/server/accessors/SlashCommandsExtend.ts b/packages/apps/src/server/accessors/SlashCommandsExtend.ts deleted file mode 100644 index 981dc8d01ffe7..0000000000000 --- a/packages/apps/src/server/accessors/SlashCommandsExtend.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { ISlashCommandsExtend } from '@rocket.chat/apps-engine/definition/accessors'; -import type { ISlashCommand } from '@rocket.chat/apps-engine/definition/slashcommands'; - -import type { AppSlashCommandManager } from '../managers/AppSlashCommandManager'; - -export class SlashCommandsExtend implements ISlashCommandsExtend { - constructor( - private readonly manager: AppSlashCommandManager, - private readonly appId: string, - ) {} - - public async provideSlashCommand(slashCommand: ISlashCommand): Promise { - await this.manager.addCommand(this.appId, slashCommand); - } -} diff --git a/packages/apps/src/server/accessors/SlashCommandsModify.ts b/packages/apps/src/server/accessors/SlashCommandsModify.ts deleted file mode 100644 index 469f9cda3c37d..0000000000000 --- a/packages/apps/src/server/accessors/SlashCommandsModify.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { ISlashCommandsModify } from '@rocket.chat/apps-engine/definition/accessors'; -import type { ISlashCommand } from '@rocket.chat/apps-engine/definition/slashcommands'; - -import type { AppSlashCommandManager } from '../managers'; - -export class SlashCommandsModify implements ISlashCommandsModify { - constructor( - private readonly manager: AppSlashCommandManager, - private readonly appId: string, - ) {} - - public modifySlashCommand(slashCommand: ISlashCommand): Promise { - return Promise.resolve(this.manager.modifyCommand(this.appId, slashCommand)); - } - - public disableSlashCommand(command: string): Promise { - return Promise.resolve(this.manager.disableCommand(this.appId, command)); - } - - public enableSlashCommand(command: string): Promise { - return Promise.resolve(this.manager.enableCommand(this.appId, command)); - } -} diff --git a/packages/apps/src/server/accessors/ThreadRead.ts b/packages/apps/src/server/accessors/ThreadRead.ts deleted file mode 100644 index 1cb6a6a66a6a9..0000000000000 --- a/packages/apps/src/server/accessors/ThreadRead.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { IThreadRead } from '@rocket.chat/apps-engine/definition/accessors/IThreadRead'; -import type { IMessage } from '@rocket.chat/apps-engine/definition/messages'; - -import type { ThreadBridge } from '../bridges/ThreadBridge'; - -export class ThreadRead implements IThreadRead { - constructor( - private threadBridge: ThreadBridge, - private appId: string, - ) {} - - public getThreadById(id: string): Promise> { - return this.threadBridge.doGetById(id, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/UIController.ts b/packages/apps/src/server/accessors/UIController.ts deleted file mode 100644 index e21cf80b845f1..0000000000000 --- a/packages/apps/src/server/accessors/UIController.ts +++ /dev/null @@ -1,126 +0,0 @@ -import type { IUIController } from '@rocket.chat/apps-engine/definition/accessors'; -import type { - IUIKitErrorInteractionParam, - IUIKitInteractionParam, - IUIKitSurfaceViewParam, -} from '@rocket.chat/apps-engine/definition/accessors/IUIController'; -import { UIKitInteractionType, UIKitSurfaceType } from '@rocket.chat/apps-engine/definition/uikit'; -import { - formatContextualBarInteraction, - formatErrorInteraction, - formatModalInteraction, -} from '@rocket.chat/apps-engine/definition/uikit/UIKitInteractionPayloadFormatter'; -import type { - IUIKitContextualBarViewParam, - IUIKitModalViewParam, -} from '@rocket.chat/apps-engine/definition/uikit/UIKitInteractionResponder'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import type { AppBridges, UiInteractionBridge } from '../bridges'; -import { UIHelper } from '../misc/UIHelper'; - -export class UIController implements IUIController { - private readonly uiInteractionBridge: UiInteractionBridge; - - constructor( - private readonly appId: string, - bridges: AppBridges, - ) { - this.uiInteractionBridge = bridges.getUiInteractionBridge(); - } - - /** - * @deprecated please prefer the `openSurfaceView` method - */ - public openModalView(view: IUIKitModalViewParam, context: IUIKitInteractionParam, user: IUser) { - return this.openModal(view, context, user); - } - - /** - * @deprecated please prefer the `updateSurfaceView` method - */ - public updateModalView(view: IUIKitModalViewParam, context: IUIKitInteractionParam, user: IUser) { - return this.openModal(view, context, user, true); - } - - /** - * @deprecated please prefer the `openSurfaceView` method - */ - public openContextualBarView(view: IUIKitContextualBarViewParam, context: IUIKitInteractionParam, user: IUser) { - return this.openContextualBar(view, context, user); - } - - /** - * @deprecated please prefer the `updateSurfaceView` method - */ - public updateContextualBarView(view: IUIKitContextualBarViewParam, context: IUIKitInteractionParam, user: IUser) { - return this.openContextualBar(view, context, user, true); - } - - public openSurfaceView(view: IUIKitSurfaceViewParam, context: IUIKitInteractionParam, user: IUser) { - const blocks = UIHelper.assignIds(view.blocks, this.appId); - const viewWithIds = { ...view, blocks }; - - switch (view.type) { - case UIKitSurfaceType.CONTEXTUAL_BAR: - return this.openContextualBar(viewWithIds, context, user); - case UIKitSurfaceType.MODAL: - return this.openModal(viewWithIds, context, user); - } - } - - public updateSurfaceView(view: IUIKitSurfaceViewParam, context: IUIKitInteractionParam, user: IUser) { - const blocks = UIHelper.assignIds(view.blocks, this.appId); - const viewWithIds = { ...view, blocks }; - - switch (view.type) { - case UIKitSurfaceType.CONTEXTUAL_BAR: - return this.openContextualBar(viewWithIds, context, user, true); - case UIKitSurfaceType.MODAL: - return this.openModal(viewWithIds, context, user, true); - } - } - - public setViewError(errorInteraction: IUIKitErrorInteractionParam, context: IUIKitInteractionParam, user: IUser) { - const interactionContext = { - ...context, - type: UIKitInteractionType.ERRORS, - appId: this.appId, - }; - - return this.uiInteractionBridge.doNotifyUser(user, formatErrorInteraction(errorInteraction, interactionContext), this.appId); - } - - private openContextualBar( - view: IUIKitContextualBarViewParam, - context: IUIKitInteractionParam, - user: IUser, - isUpdate = false, - ): Promise { - let type = UIKitInteractionType.CONTEXTUAL_BAR_OPEN; - if (isUpdate) { - type = UIKitInteractionType.CONTEXTUAL_BAR_UPDATE; - } - const interactionContext = { - ...context, - type, - appId: this.appId, - }; - - return this.uiInteractionBridge.doNotifyUser(user, formatContextualBarInteraction(view, interactionContext), this.appId); - } - - private openModal(view: IUIKitModalViewParam, context: IUIKitInteractionParam, user: IUser, isUpdate = false): Promise { - let type = UIKitInteractionType.MODAL_OPEN; - if (isUpdate) { - type = UIKitInteractionType.MODAL_UPDATE; - } - const interactionContext = { - ...context, - type, - appId: this.appId, - }; - - return this.uiInteractionBridge.doNotifyUser(user, formatModalInteraction(view, interactionContext), this.appId); - } -} diff --git a/packages/apps/src/server/accessors/UIExtend.ts b/packages/apps/src/server/accessors/UIExtend.ts deleted file mode 100644 index 7369461dae569..0000000000000 --- a/packages/apps/src/server/accessors/UIExtend.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { IUIExtend } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IUIActionButtonDescriptor } from '@rocket.chat/apps-engine/definition/ui'; - -import type { UIActionButtonManager } from '../managers/UIActionButtonManager'; - -export class UIExtend implements IUIExtend { - constructor( - private readonly manager: UIActionButtonManager, - private readonly appId: string, - ) {} - - public registerButton(button: IUIActionButtonDescriptor): void { - this.manager.registerActionButton(this.appId, button); - } -} diff --git a/packages/apps/src/server/accessors/UploadCreator.ts b/packages/apps/src/server/accessors/UploadCreator.ts deleted file mode 100644 index f33a30f0e4259..0000000000000 --- a/packages/apps/src/server/accessors/UploadCreator.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { IUploadCreator } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IUpload } from '@rocket.chat/apps-engine/definition/uploads'; -import type { IUploadDescriptor } from '@rocket.chat/apps-engine/definition/uploads/IUploadDescriptor'; -import type { IUploadDetails } from '@rocket.chat/apps-engine/definition/uploads/IUploadDetails'; - -import type { AppBridges } from '../bridges'; - -export class UploadCreator implements IUploadCreator { - constructor( - private readonly bridges: AppBridges, - private readonly appId: string, - ) {} - - public async uploadBuffer(buffer: Buffer, descriptor: IUploadDescriptor): Promise { - if (!Object.hasOwn(descriptor, 'user') && !descriptor.visitorToken) { - descriptor.user = await this.bridges.getUserBridge().doGetAppUser(this.appId); - } - - const details = { - name: descriptor.filename, - size: buffer.length, - rid: descriptor.room.id, - userId: descriptor.user?.id, - visitorToken: descriptor.visitorToken, - } as IUploadDetails; - - return this.bridges.getUploadBridge().doCreateUpload(details, buffer, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/UploadRead.ts b/packages/apps/src/server/accessors/UploadRead.ts deleted file mode 100644 index 5df4ed5b2755c..0000000000000 --- a/packages/apps/src/server/accessors/UploadRead.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { IUploadRead } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IUpload } from '@rocket.chat/apps-engine/definition/uploads'; - -import type { UploadBridge } from '../bridges/UploadBridge'; - -export class UploadRead implements IUploadRead { - constructor( - private readonly uploadBridge: UploadBridge, - private readonly appId: string, - ) {} - - public getById(id: string): Promise { - return this.uploadBridge.doGetById(id, this.appId); - } - - public getBuffer(upload: IUpload): Promise { - return this.uploadBridge.doGetBuffer(upload, this.appId); - } - - public async getBufferById(id: string): Promise { - const upload = await this.uploadBridge.doGetById(id, this.appId); - - return this.uploadBridge.doGetBuffer(upload, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/UserBuilder.ts b/packages/apps/src/server/accessors/UserBuilder.ts deleted file mode 100644 index f1c891ec73bd6..0000000000000 --- a/packages/apps/src/server/accessors/UserBuilder.ts +++ /dev/null @@ -1,74 +0,0 @@ -import type { IUserBuilder } from '@rocket.chat/apps-engine/definition/accessors'; -import { RocketChatAssociationModel } from '@rocket.chat/apps-engine/definition/metadata'; -import type { IUser, IUserEmail } from '@rocket.chat/apps-engine/definition/users'; -import type { IUserSettings } from '@rocket.chat/apps-engine/definition/users/IUserSettings'; - -export class UserBuilder implements IUserBuilder { - public kind: RocketChatAssociationModel.USER; - - private user: Partial; - - constructor(user?: Partial) { - this.kind = RocketChatAssociationModel.USER; - this.user = user || ({} as Partial); - } - - public setData(data: Partial): IUserBuilder { - delete data.id; - this.user = data; - - return this; - } - - public setEmails(emails: Array): IUserBuilder { - this.user.emails = emails; - return this; - } - - public getEmails(): Array { - return this.user.emails; - } - - public setDisplayName(name: string): IUserBuilder { - this.user.name = name; - return this; - } - - public getDisplayName(): string { - return this.user.name; - } - - public setUsername(username: string): IUserBuilder { - this.user.username = username; - return this; - } - - public getUsername(): string { - return this.user.username; - } - - public setRoles(roles: Array): IUserBuilder { - this.user.roles = roles; - return this; - } - - public getRoles(): Array { - return this.user.roles; - } - - public getSettings(): Partial { - return this.user.settings; - } - - public getUser(): Partial { - if (!this.user.username) { - throw new Error('The "username" property is required.'); - } - - if (!this.user.name) { - throw new Error('The "name" property is required.'); - } - - return this.user; - } -} diff --git a/packages/apps/src/server/accessors/UserRead.ts b/packages/apps/src/server/accessors/UserRead.ts deleted file mode 100644 index 1d6a6d0d4c55a..0000000000000 --- a/packages/apps/src/server/accessors/UserRead.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { IUserRead } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import type { UserBridge } from '../bridges/UserBridge'; - -export class UserRead implements IUserRead { - constructor( - private userBridge: UserBridge, - private appId: string, - ) {} - - public getById(id: string): Promise { - return this.userBridge.doGetById(id, this.appId); - } - - public getByUsername(username: string): Promise { - return this.userBridge.doGetByUsername(username, this.appId); - } - - public getBySipExtension(extension: string): Promise { - if (!extension) { - return Promise.resolve(undefined); - } - - return this.userBridge.doGetBySipExtension(extension, this.appId); - } - - public getAppUser(appId: string = this.appId): Promise { - return this.userBridge.doGetAppUser(appId); - } - - public getUserUnreadMessageCount(uid: string): Promise { - return this.userBridge.doGetUserUnreadMessageCount(uid, this.appId); - } - - public getUserRoomIds(userId: string): Promise { - return this.userBridge.doGetUserRoomIds(userId, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/UserUpdater.ts b/packages/apps/src/server/accessors/UserUpdater.ts deleted file mode 100644 index 4eb2e5f11b42b..0000000000000 --- a/packages/apps/src/server/accessors/UserUpdater.ts +++ /dev/null @@ -1,43 +0,0 @@ -import type { IUserUpdater } from '@rocket.chat/apps-engine/definition/accessors/IUserUpdater'; -import type { UserStatusConnection } from '@rocket.chat/apps-engine/definition/users'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users/IUser'; - -import type { AppBridges } from '../bridges'; - -export class UserUpdater implements IUserUpdater { - constructor( - private readonly bridges: AppBridges, - private readonly appId: string, - ) {} - - public async updateStatusText(user: IUser, statusText: IUser['statusText']) { - return this.bridges.getUserBridge().doUpdate(user, { statusText }, this.appId); - } - - public async updateStatus(user: IUser, statusText: IUser['statusText'], status: UserStatusConnection) { - return this.bridges.getUserBridge().doUpdate(user, { statusText, status }, this.appId); - } - - public async updateBio(user: IUser, bio: IUser['bio']) { - return this.bridges.getUserBridge().doUpdate(user, { bio }, this.appId); - } - - public async updateCustomFields(user: IUser, customFields: IUser['customFields']) { - return this.bridges.getUserBridge().doUpdate(user, { customFields }, this.appId); - } - - public async deactivate(userId: IUser['id'], confirmRelinquish: boolean) { - return this.bridges.getUserBridge().doDeactivate(userId, confirmRelinquish, this.appId); - } - - public async setActiveState( - userId: IUser['id'], - state: Pick, - ) { - return this.bridges.getUserBridge().doSetActiveState(userId, state, this.appId); - } - - public async endActiveState(userId: IUser['id'], statusId?: string) { - return this.bridges.getUserBridge().doEndActiveState(userId, this.appId, statusId); - } -} diff --git a/packages/apps/src/server/accessors/VideoConfProviderExtend.ts b/packages/apps/src/server/accessors/VideoConfProviderExtend.ts deleted file mode 100644 index 45bb2b174e381..0000000000000 --- a/packages/apps/src/server/accessors/VideoConfProviderExtend.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { IVideoConfProvidersExtend } from '@rocket.chat/apps-engine/definition/accessors'; -import type { IVideoConfProvider } from '@rocket.chat/apps-engine/definition/videoConfProviders'; - -import type { AppVideoConfProviderManager } from '../managers/AppVideoConfProviderManager'; - -export class VideoConfProviderExtend implements IVideoConfProvidersExtend { - constructor( - private readonly manager: AppVideoConfProviderManager, - private readonly appId: string, - ) {} - - public provideVideoConfProvider(provider: IVideoConfProvider): Promise { - return Promise.resolve(this.manager.addProvider(this.appId, provider)); - } -} diff --git a/packages/apps/src/server/accessors/VideoConferenceBuilder.ts b/packages/apps/src/server/accessors/VideoConferenceBuilder.ts deleted file mode 100644 index a7c101b9851e7..0000000000000 --- a/packages/apps/src/server/accessors/VideoConferenceBuilder.ts +++ /dev/null @@ -1,83 +0,0 @@ -import type { IVideoConferenceBuilder } from '@rocket.chat/apps-engine/definition/accessors'; -import { RocketChatAssociationModel } from '@rocket.chat/apps-engine/definition/metadata'; -import type { AppVideoConference } from '@rocket.chat/apps-engine/definition/videoConferences'; - -export class VideoConferenceBuilder implements IVideoConferenceBuilder { - public kind: RocketChatAssociationModel.VIDEO_CONFERENCE = RocketChatAssociationModel.VIDEO_CONFERENCE; - - protected call: AppVideoConference; - - constructor(data?: Partial) { - this.call = (data || {}) as AppVideoConference; - } - - public setData(data: Partial): IVideoConferenceBuilder { - this.call = { - rid: data.rid, - createdBy: data.createdBy, - providerName: data.providerName, - title: data.title, - discussionRid: data.discussionRid, - }; - - return this; - } - - public setRoomId(rid: string): IVideoConferenceBuilder { - this.call.rid = rid; - return this; - } - - public getRoomId(): string { - return this.call.rid; - } - - public setCreatedBy(userId: string): IVideoConferenceBuilder { - this.call.createdBy = userId; - return this; - } - - public getCreatedBy(): string { - return this.call.createdBy; - } - - public setProviderName(userId: string): IVideoConferenceBuilder { - this.call.providerName = userId; - return this; - } - - public getProviderName(): string { - return this.call.providerName; - } - - public setProviderData(data: Record | undefined): IVideoConferenceBuilder { - this.call.providerData = data; - return this; - } - - public getProviderData(): Record | undefined { - return this.call.providerData; - } - - public setTitle(userId: string): IVideoConferenceBuilder { - this.call.title = userId; - return this; - } - - public getTitle(): string { - return this.call.title; - } - - public setDiscussionRid(rid: AppVideoConference['discussionRid']): IVideoConferenceBuilder { - this.call.discussionRid = rid; - return this; - } - - public getDiscussionRid(): AppVideoConference['discussionRid'] { - return this.call.discussionRid; - } - - public getVideoConference(): AppVideoConference { - return this.call; - } -} diff --git a/packages/apps/src/server/accessors/VideoConferenceExtend.ts b/packages/apps/src/server/accessors/VideoConferenceExtend.ts deleted file mode 100644 index 01c816bf952ad..0000000000000 --- a/packages/apps/src/server/accessors/VideoConferenceExtend.ts +++ /dev/null @@ -1,65 +0,0 @@ -import type { IVideoConferenceExtender } from '@rocket.chat/apps-engine/definition/accessors'; -import { RocketChatAssociationModel } from '@rocket.chat/apps-engine/definition/metadata'; -import type { IVideoConferenceUser, VideoConference } from '@rocket.chat/apps-engine/definition/videoConferences'; -import type { VideoConferenceMember } from '@rocket.chat/apps-engine/definition/videoConferences/IVideoConference'; - -import { Utilities } from '../misc/Utilities'; - -export class VideoConferenceExtender implements IVideoConferenceExtender { - public kind: RocketChatAssociationModel.VIDEO_CONFERENCE; - - constructor(private videoConference: VideoConference) { - this.kind = RocketChatAssociationModel.VIDEO_CONFERENCE; - } - - public setProviderData(value: Record): IVideoConferenceExtender { - this.videoConference.providerData = value; - - return this; - } - - public setStatus(value: VideoConference['status']): IVideoConferenceExtender { - this.videoConference.status = value; - - return this; - } - - public setEndedBy(value: IVideoConferenceUser['_id']): IVideoConferenceExtender { - this.videoConference.endedBy = { - _id: value, - // Name and username will be loaded automatically by the bridge - username: '', - name: '', - }; - - return this; - } - - public setEndedAt(value: VideoConference['endedAt']): IVideoConferenceExtender { - this.videoConference.endedAt = value; - - return this; - } - - public addUser(userId: VideoConferenceMember['_id'], ts?: VideoConferenceMember['ts']): IVideoConferenceExtender { - this.videoConference.users.push({ - _id: userId, - ts, - // Name and username will be loaded automatically by the bridge - username: '', - name: '', - }); - - return this; - } - - public setDiscussionRid(rid: VideoConference['discussionRid']): IVideoConferenceExtender { - this.videoConference.discussionRid = rid; - - return this; - } - - public getVideoConference(): VideoConference { - return Utilities.deepClone(this.videoConference); - } -} diff --git a/packages/apps/src/server/accessors/VideoConferenceRead.ts b/packages/apps/src/server/accessors/VideoConferenceRead.ts deleted file mode 100644 index 02dc89e356dd6..0000000000000 --- a/packages/apps/src/server/accessors/VideoConferenceRead.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { IVideoConferenceRead } from '@rocket.chat/apps-engine/definition/accessors'; -import type { VideoConference } from '@rocket.chat/apps-engine/definition/videoConferences'; - -import type { VideoConferenceBridge } from '../bridges'; - -export class VideoConferenceRead implements IVideoConferenceRead { - constructor( - private videoConfBridge: VideoConferenceBridge, - private appId: string, - ) {} - - public getById(id: string): Promise { - return this.videoConfBridge.doGetById(id, this.appId); - } -} diff --git a/packages/apps/src/server/accessors/index.ts b/packages/apps/src/server/accessors/index.ts deleted file mode 100644 index eb5cbdc0218c7..0000000000000 --- a/packages/apps/src/server/accessors/index.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { ApiExtend } from './ApiExtend'; -import { AppAccessors } from './AppAccessors'; -import { ConfigurationExtend } from './ConfigurationExtend'; -import { ConfigurationModify } from './ConfigurationModify'; -import { EnvironmentRead } from './EnvironmentRead'; -import { EnvironmentWrite } from './EnvironmentWrite'; -import { EnvironmentalVariableRead } from './EnvironmentalVariableRead'; -import { ExternalComponentsExtend } from './ExternalComponentsExtend'; -import { Http } from './Http'; -import { HttpExtend } from './HttpExtend'; -import { LivechatRead } from './LivechatRead'; -import { MessageBuilder } from './MessageBuilder'; -import { MessageExtender } from './MessageExtender'; -import { MessageRead } from './MessageRead'; -import { ModerationModify } from './ModerationModify'; -import { Modify } from './Modify'; -import { ModifyCreator } from './ModifyCreator'; -import { ModifyExtender } from './ModifyExtender'; -import { ModifyUpdater } from './ModifyUpdater'; -import { Notifier } from './Notifier'; -import { OAuthAppsModify } from './OAuthAppsModify'; -import { OAuthAppsReader } from './OAuthAppsReader'; -import { OutboundMessageProviderExtend } from './OutboundCommunicationProviderExtend'; -import { Persistence } from './Persistence'; -import { PersistenceRead } from './PersistenceRead'; -import { Reader } from './Reader'; -import { RoleRead } from './RoleRead'; -import { RoomBuilder } from './RoomBuilder'; -import { RoomExtender } from './RoomExtender'; -import { RoomRead } from './RoomRead'; -import { SchedulerExtend } from './SchedulerExtend'; -import { SchedulerModify } from './SchedulerModify'; -import { ServerSettingRead } from './ServerSettingRead'; -import { ServerSettingUpdater } from './ServerSettingUpdater'; -import { ServerSettingsModify } from './ServerSettingsModify'; -import { SettingRead } from './SettingRead'; -import { SettingUpdater } from './SettingUpdater'; -import { SettingsExtend } from './SettingsExtend'; -import { SlashCommandsExtend } from './SlashCommandsExtend'; -import { SlashCommandsModify } from './SlashCommandsModify'; -import { UploadRead } from './UploadRead'; -import { UserBuilder } from './UserBuilder'; -import { UserRead } from './UserRead'; -import { VideoConfProviderExtend } from './VideoConfProviderExtend'; -import { VideoConferenceBuilder } from './VideoConferenceBuilder'; -import { VideoConferenceExtender } from './VideoConferenceExtend'; -import { VideoConferenceRead } from './VideoConferenceRead'; - -export { - ApiExtend, - AppAccessors, - ConfigurationExtend, - ConfigurationModify, - EnvironmentalVariableRead, - EnvironmentRead, - EnvironmentWrite, - ExternalComponentsExtend, - Http, - HttpExtend, - LivechatRead, - MessageBuilder, - MessageExtender, - MessageRead, - ModerationModify, - Modify, - ModifyCreator, - ModifyExtender, - ModifyUpdater, - Notifier, - Persistence, - PersistenceRead, - Reader, - RoleRead, - RoomBuilder, - RoomExtender, - RoomRead, - ServerSettingRead, - ServerSettingsModify, - ServerSettingUpdater, - SettingRead, - SettingsExtend, - SettingUpdater, - SlashCommandsExtend, - SlashCommandsModify, - UploadRead, - UserBuilder, - UserRead, - SchedulerExtend, - SchedulerModify, - VideoConferenceBuilder, - VideoConferenceExtender, - VideoConferenceRead, - VideoConfProviderExtend, - OAuthAppsModify, - OAuthAppsReader, - OutboundMessageProviderExtend, -}; diff --git a/packages/apps/src/server/managers/AppAccessorManager.ts b/packages/apps/src/server/managers/AppAccessorManager.ts deleted file mode 100644 index 57681c85856d5..0000000000000 --- a/packages/apps/src/server/managers/AppAccessorManager.ts +++ /dev/null @@ -1,252 +0,0 @@ -import type { - IConfigurationExtend, - IConfigurationModify, - IEnvironmentRead, - IEnvironmentWrite, - IHttp, - IHttpExtend, - IModify, - IPersistence, - IRead, -} from '@rocket.chat/apps-engine/definition/accessors'; - -import type { AppManager } from '../AppManager'; -import { - ApiExtend, - ConfigurationExtend, - ConfigurationModify, - EnvironmentalVariableRead, - EnvironmentRead, - EnvironmentWrite, - ExternalComponentsExtend, - Http, - HttpExtend, - LivechatRead, - MessageRead, - Modify, - Notifier, - OAuthAppsReader, - OutboundMessageProviderExtend, - Persistence, - PersistenceRead, - Reader, - RoleRead, - RoomRead, - SchedulerExtend, - SchedulerModify, - ServerSettingRead, - ServerSettingsModify, - ServerSettingUpdater, - SettingRead, - SettingsExtend, - SettingUpdater, - SlashCommandsExtend, - SlashCommandsModify, - UploadRead, - UserRead, - VideoConferenceRead, - VideoConfProviderExtend, -} from '../accessors'; -import { CloudWorkspaceRead } from '../accessors/CloudWorkspaceRead'; -import { ContactRead } from '../accessors/ContactRead'; -import { ExperimentalRead } from '../accessors/ExperimentalRead'; -import { ThreadRead } from '../accessors/ThreadRead'; -import { UIExtend } from '../accessors/UIExtend'; -import type { AppBridges } from '../bridges/AppBridges'; - -export class AppAccessorManager { - private readonly bridges: AppBridges; - - private readonly configExtenders: Map; - - private readonly envReaders: Map; - - private readonly envWriters: Map; - - private readonly configModifiers: Map; - - private readonly readers: Map; - - private readonly modifiers: Map; - - private readonly persists: Map; - - private readonly https: Map; - - constructor(private readonly manager: AppManager) { - this.bridges = this.manager.getBridges(); - this.configExtenders = new Map(); - this.envReaders = new Map(); - this.envWriters = new Map(); - this.configModifiers = new Map(); - this.readers = new Map(); - this.modifiers = new Map(); - this.persists = new Map(); - this.https = new Map(); - } - - /** - * Purifies the accessors for the provided App. - * - * @param appId The id of the App to purge the accessors for. - */ - public purifyApp(appId: string): void { - this.configExtenders.delete(appId); - this.envReaders.delete(appId); - this.envWriters.delete(appId); - this.configModifiers.delete(appId); - this.readers.delete(appId); - this.modifiers.delete(appId); - this.persists.delete(appId); - this.https.delete(appId); - } - - public getConfigurationExtend(appId: string): IConfigurationExtend { - if (!this.configExtenders.has(appId)) { - const rl = this.manager.getOneById(appId); - - if (!rl) { - throw new Error(`No App found by the provided id: ${appId}`); - } - - const htt = new HttpExtend(); - const cmds = new SlashCommandsExtend(this.manager.getCommandManager(), appId); - const videoConf = new VideoConfProviderExtend(this.manager.getVideoConfProviderManager(), appId); - const apis = new ApiExtend(this.manager.getApiManager(), appId); - const sets = new SettingsExtend(rl); - const excs = new ExternalComponentsExtend(this.manager.getExternalComponentManager(), appId); - const scheduler = new SchedulerExtend(this.manager.getSchedulerManager(), appId); - const ui = new UIExtend(this.manager.getUIActionButtonManager(), appId); - const outboundComms = new OutboundMessageProviderExtend(this.manager.getOutboundCommunicationProviderManager(), appId); - - this.configExtenders.set(appId, new ConfigurationExtend(htt, sets, cmds, apis, excs, scheduler, ui, videoConf, outboundComms)); - } - - return this.configExtenders.get(appId); - } - - public getEnvironmentRead(appId: string): IEnvironmentRead { - if (!this.envReaders.has(appId)) { - const rl = this.manager.getOneById(appId); - - if (!rl) { - throw new Error(`No App found by the provided id: ${appId}`); - } - - const sets = new SettingRead(rl); - const servsets = new ServerSettingRead(this.bridges.getServerSettingBridge(), appId); - const env = new EnvironmentalVariableRead(this.bridges.getEnvironmentalVariableBridge(), appId); - - this.envReaders.set(appId, new EnvironmentRead(sets, servsets, env)); - } - - return this.envReaders.get(appId); - } - - public getEnvironmentWrite(appId: string): IEnvironmentWrite { - if (!this.envWriters.has(appId)) { - const rl = this.manager.getOneById(appId); - - if (!rl) { - throw new Error(`No App found by the provided id: ${appId}`); - } - - const sets = new SettingUpdater(rl, this.manager.getSettingsManager()); - const serverSetting = new ServerSettingUpdater(this.bridges, appId); - - this.envWriters.set(appId, new EnvironmentWrite(sets, serverSetting)); - } - - return this.envWriters.get(appId); - } - - public getConfigurationModify(appId: string): IConfigurationModify { - if (!this.configModifiers.has(appId)) { - this.configModifiers.set( - appId, - new ConfigurationModify( - new ServerSettingsModify(this.bridges.getServerSettingBridge(), appId), - new SlashCommandsModify(this.manager.getCommandManager(), appId), - new SchedulerModify(this.bridges.getSchedulerBridge(), appId), - ), - ); - } - - return this.configModifiers.get(appId); - } - - public getReader(appId: string): IRead { - if (!this.readers.has(appId)) { - const env = this.getEnvironmentRead(appId); - const msg = new MessageRead(this.bridges.getMessageBridge(), appId); - const persist = new PersistenceRead(this.bridges.getPersistenceBridge(), appId); - const room = new RoomRead(this.bridges.getRoomBridge(), appId); - const user = new UserRead(this.bridges.getUserBridge(), appId); - const noti = new Notifier(this.bridges.getUserBridge(), this.bridges.getMessageBridge(), appId); - const livechat = new LivechatRead(this.bridges.getLivechatBridge(), appId); - const upload = new UploadRead(this.bridges.getUploadBridge(), appId); - const cloud = new CloudWorkspaceRead(this.bridges.getCloudWorkspaceBridge(), appId); - const videoConf = new VideoConferenceRead(this.bridges.getVideoConferenceBridge(), appId); - const oauthApps = new OAuthAppsReader(this.bridges.getOAuthAppsBridge(), appId); - const contactReader = new ContactRead(this.bridges, appId); - const thread = new ThreadRead(this.bridges.getThreadBridge(), appId); - const role = new RoleRead(this.bridges.getRoleBridge(), appId); - const experimental = new ExperimentalRead(this.bridges.getExperimentalBridge(), appId); - - this.readers.set( - appId, - new Reader( - env, - msg, - persist, - room, - user, - noti, - livechat, - upload, - cloud, - videoConf, - contactReader, - oauthApps, - thread, - role, - experimental, - ), - ); - } - - return this.readers.get(appId); - } - - public getModifier(appId: string): IModify { - if (!this.modifiers.has(appId)) { - this.modifiers.set(appId, new Modify(this.bridges, appId)); - } - - return this.modifiers.get(appId); - } - - public getPersistence(appId: string): IPersistence { - if (!this.persists.has(appId)) { - this.persists.set(appId, new Persistence(this.bridges.getPersistenceBridge(), appId)); - } - - return this.persists.get(appId); - } - - public getHttp(appId: string): IHttp { - if (!this.https.has(appId)) { - let ext: IHttpExtend; - if (this.configExtenders.has(appId)) { - ext = this.configExtenders.get(appId).http; - } else { - const cf = this.getConfigurationExtend(appId); - ext = cf.http; - } - - this.https.set(appId, new Http(this, this.bridges, ext, appId)); - } - - return this.https.get(appId); - } -} diff --git a/packages/apps/src/server/managers/AppApi.ts b/packages/apps/src/server/managers/AppApi.ts index 88205731dd0da..e16a337ea2e9e 100644 --- a/packages/apps/src/server/managers/AppApi.ts +++ b/packages/apps/src/server/managers/AppApi.ts @@ -5,7 +5,6 @@ import type { IApiEndpointInfo } from '@rocket.chat/apps-engine/definition/api/I import type { ProxiedApp } from '../ProxiedApp'; import type { AppLogStorage } from '../storage'; -import type { AppAccessorManager } from './AppAccessorManager'; export class AppApi { public readonly computedPath: string; @@ -41,7 +40,7 @@ export class AppApi { this.implementedMethods = endpoint._availableMethods; } - public async runExecutor(request: IApiRequest, _logStorage: AppLogStorage, _accessors: AppAccessorManager): Promise { + public async runExecutor(request: IApiRequest, _logStorage: AppLogStorage): Promise { const { path } = this.endpoint; const { method } = request; diff --git a/packages/apps/src/server/managers/AppApiManager.ts b/packages/apps/src/server/managers/AppApiManager.ts index e553eef9743ef..72cc68940e406 100644 --- a/packages/apps/src/server/managers/AppApiManager.ts +++ b/packages/apps/src/server/managers/AppApiManager.ts @@ -5,7 +5,6 @@ import type { IApi, IApiEndpointMetadata, IApiRequest, IApiResponse } from '@roc import type { AppManager } from '../AppManager'; import type { ApiBridge } from '../bridges'; import { PathAlreadyExistsError } from '../errors'; -import type { AppAccessorManager } from './AppAccessorManager'; import { AppApi } from './AppApi'; /** @@ -18,15 +17,12 @@ import { AppApi } from './AppApi'; export class AppApiManager { private readonly bridge: ApiBridge; - private readonly accessors: AppAccessorManager; - // Variable that contains the api's which have been provided by apps. // The key of the top map is app id and the key of the inner map is the path private providedApis: Map>; constructor(private readonly manager: AppManager) { this.bridge = this.manager.getBridges().getApiBridge(); - this.accessors = this.manager.getAccessorManager(); this.providedApis = new Map>(); } @@ -123,7 +119,7 @@ export class AppApiManager { }; } - return api.runExecutor(request, this.manager.getLogStorage(), this.accessors); + return api.runExecutor(request, this.manager.getLogStorage()); } /** diff --git a/packages/apps/src/server/managers/AppOutboundCommunicationProvider.ts b/packages/apps/src/server/managers/AppOutboundCommunicationProvider.ts index ad93ea1e4136c..4cd5e54797bae 100644 --- a/packages/apps/src/server/managers/AppOutboundCommunicationProvider.ts +++ b/packages/apps/src/server/managers/AppOutboundCommunicationProvider.ts @@ -5,7 +5,6 @@ import type { ProviderMetadata, } from '@rocket.chat/apps-engine/definition/outboundCommunication'; -import type { AppAccessorManager } from '.'; import type { ProxiedApp } from '../ProxiedApp'; import { AppOutboundProcessError } from '../errors/AppOutboundProcessError'; import type { AppLogStorage } from '../storage'; @@ -20,18 +19,17 @@ export class OutboundMessageProvider { this.isRegistered = false; } - public async runGetProviderMetadata(logStorage: AppLogStorage, accessors: AppAccessorManager): Promise { - return this.runTheCode(AppMethod._OUTBOUND_GET_PROVIDER_METADATA, logStorage, accessors, []); + public async runGetProviderMetadata(logStorage: AppLogStorage): Promise { + return this.runTheCode(AppMethod._OUTBOUND_GET_PROVIDER_METADATA, logStorage, []); } - public async runSendOutboundMessage(logStorage: AppLogStorage, accessors: AppAccessorManager, body: IOutboundMessage): Promise { - await this.runTheCode(AppMethod._OUTBOUND_SEND_MESSAGE, logStorage, accessors, [body]); + public async runSendOutboundMessage(logStorage: AppLogStorage, body: IOutboundMessage): Promise { + await this.runTheCode(AppMethod._OUTBOUND_SEND_MESSAGE, logStorage, [body]); } private async runTheCode( method: AppMethod._OUTBOUND_GET_PROVIDER_METADATA | AppMethod._OUTBOUND_SEND_MESSAGE, _logStorage: AppLogStorage, - _accessors: AppAccessorManager, runContextArgs: Array, ): Promise { const provider = `${this.provider.name}-${this.provider.type}`; diff --git a/packages/apps/src/server/managers/AppOutboundCommunicationProviderManager.ts b/packages/apps/src/server/managers/AppOutboundCommunicationProviderManager.ts index a4767c2ab665b..a07793abb1b71 100644 --- a/packages/apps/src/server/managers/AppOutboundCommunicationProviderManager.ts +++ b/packages/apps/src/server/managers/AppOutboundCommunicationProviderManager.ts @@ -6,7 +6,6 @@ import type { IOutboundMessage, } from '@rocket.chat/apps-engine/definition/outboundCommunication'; -import type { AppAccessorManager } from '.'; import type { AppManager } from '../AppManager'; import type { OutboundMessageBridge } from '../bridges'; import { OutboundMessageProvider } from './AppOutboundCommunicationProvider'; @@ -15,15 +14,12 @@ import { PermissionDeniedError } from '../errors/PermissionDeniedError'; import { AppPermissions } from '../permissions/AppPermissions'; export class AppOutboundCommunicationProviderManager { - private readonly accessors: AppAccessorManager; - private readonly bridge: OutboundMessageBridge; private outboundMessageProviders: Map>; constructor(private readonly manager: AppManager) { this.bridge = this.manager.getBridges().getOutboundMessageBridge(); - this.accessors = this.manager.getAccessorManager(); this.outboundMessageProviders = new Map>(); } @@ -125,7 +121,7 @@ export class AppOutboundCommunicationProviderManager { throw new Error('provider-not-registered'); } - return providerInfo.runGetProviderMetadata(this.manager.getLogStorage(), this.accessors); + return providerInfo.runGetProviderMetadata(this.manager.getLogStorage()); } public sendOutboundMessage(appId: string, providerType: ValidOutboundProvider, body: IOutboundMessage) { @@ -134,6 +130,6 @@ export class AppOutboundCommunicationProviderManager { throw new Error('provider-not-registered'); } - return providerInfo.runSendOutboundMessage(this.manager.getLogStorage(), this.accessors, body); + return providerInfo.runSendOutboundMessage(this.manager.getLogStorage(), body); } } diff --git a/packages/apps/src/server/managers/AppSlashCommand.ts b/packages/apps/src/server/managers/AppSlashCommand.ts index a69f81112a970..3aa1cf3eeb8aa 100644 --- a/packages/apps/src/server/managers/AppSlashCommand.ts +++ b/packages/apps/src/server/managers/AppSlashCommand.ts @@ -8,7 +8,6 @@ import type { import type { ProxiedApp } from '../ProxiedApp'; import type { AppLogStorage } from '../storage'; -import type { AppAccessorManager } from './AppAccessorManager'; export class AppSlashCommand { /** @@ -47,24 +46,21 @@ export class AppSlashCommand { method: AppMethod._COMMAND_EXECUTOR | AppMethod._COMMAND_PREVIEWER, context: SlashCommandContext, logStorage: AppLogStorage, - accessors: AppAccessorManager, ): Promise { - return this.runTheCode(method, logStorage, accessors, context, []); + return this.runTheCode(method, logStorage, context, []); } public async runPreviewExecutor( previewItem: ISlashCommandPreviewItem, context: SlashCommandContext, logStorage: AppLogStorage, - accessors: AppAccessorManager, ): Promise { - await this.runTheCode(AppMethod._COMMAND_PREVIEW_EXECUTOR, logStorage, accessors, context, [previewItem]); + await this.runTheCode(AppMethod._COMMAND_PREVIEW_EXECUTOR, logStorage, context, [previewItem]); } private async runTheCode( method: AppMethod._COMMAND_EXECUTOR | AppMethod._COMMAND_PREVIEWER | AppMethod._COMMAND_PREVIEW_EXECUTOR, _logStorage: AppLogStorage, - _accessors: AppAccessorManager, context: SlashCommandContext, runContextArgs: Array, ): Promise { diff --git a/packages/apps/src/server/managers/AppSlashCommandManager.ts b/packages/apps/src/server/managers/AppSlashCommandManager.ts index 41cac1ecdd966..fe73b3f113b73 100644 --- a/packages/apps/src/server/managers/AppSlashCommandManager.ts +++ b/packages/apps/src/server/managers/AppSlashCommandManager.ts @@ -6,7 +6,6 @@ import { SlashCommandContext } from '@rocket.chat/apps-engine/definition/slashco import type { AppManager } from '../AppManager'; import type { CommandBridge } from '../bridges'; import { CommandAlreadyExistsError, CommandHasAlreadyBeenTouchedError } from '../errors'; -import type { AppAccessorManager } from './AppAccessorManager'; import { AppSlashCommand } from './AppSlashCommand'; import { Room } from '../rooms/Room'; @@ -22,8 +21,6 @@ import { Room } from '../rooms/Room'; export class AppSlashCommandManager { private readonly bridge: CommandBridge; - private readonly accessors: AppAccessorManager; - /** * Variable that contains the commands which have been provided by apps. * The key of the top map is app id and the key of the inner map is the command @@ -51,7 +48,6 @@ export class AppSlashCommandManager { constructor(private readonly manager: AppManager) { this.bridge = this.manager.getBridges().getCommandBridge(); - this.accessors = this.manager.getAccessorManager(); this.touchedCommandsToApps = new Map(); this.appsTouchedCommands = new Map>(); this.providedCommands = new Map>(); @@ -343,12 +339,7 @@ export class AppSlashCommandManager { } const appCmd = this.retrieveCommandInfo(cmd, app.getID()); - await appCmd.runExecutorOrPreviewer( - AppMethod._COMMAND_EXECUTOR, - this.ensureContext(context), - this.manager.getLogStorage(), - this.accessors, - ); + await appCmd.runExecutorOrPreviewer(AppMethod._COMMAND_EXECUTOR, this.ensureContext(context), this.manager.getLogStorage()); } public async getPreviews(command: string, context: SlashCommandContext): Promise { @@ -372,7 +363,6 @@ export class AppSlashCommandManager { AppMethod._COMMAND_PREVIEWER, this.ensureContext(context), this.manager.getLogStorage(), - this.accessors, ); if (!result) { @@ -399,7 +389,7 @@ export class AppSlashCommandManager { } const appCmd = this.retrieveCommandInfo(cmd, app.getID()); - await appCmd.runPreviewExecutor(previewItem, this.ensureContext(context), this.manager.getLogStorage(), this.accessors); + await appCmd.runPreviewExecutor(previewItem, this.ensureContext(context), this.manager.getLogStorage()); } private ensureContext(context: SlashCommandContext): SlashCommandContext { diff --git a/packages/apps/src/server/managers/AppVideoConfProvider.ts b/packages/apps/src/server/managers/AppVideoConfProvider.ts index f93196f68bfc5..e537e719621e0 100644 --- a/packages/apps/src/server/managers/AppVideoConfProvider.ts +++ b/packages/apps/src/server/managers/AppVideoConfProvider.ts @@ -10,7 +10,6 @@ import type { VideoConference } from '@rocket.chat/apps-engine/definition/videoC import type { IVideoConferenceUser } from '@rocket.chat/apps-engine/definition/videoConferences/IVideoConferenceUser'; import type { ProxiedApp } from '../ProxiedApp'; -import type { AppAccessorManager } from './AppAccessorManager'; import { JSONRPC_METHOD_NOT_FOUND } from '../runtime/base/BaseRuntimeSubprocessController'; import type { AppLogStorage } from '../storage'; @@ -31,12 +30,12 @@ export class AppVideoConfProvider { this.isRegistered = true; } - public async runIsFullyConfigured(logStorage: AppLogStorage, accessors: AppAccessorManager): Promise { - return !!(await this.runTheCode(AppMethod._VIDEOCONF_IS_CONFIGURED, logStorage, accessors, [])); + public async runIsFullyConfigured(logStorage: AppLogStorage): Promise { + return !!(await this.runTheCode(AppMethod._VIDEOCONF_IS_CONFIGURED, logStorage, [])); } - public async runGenerateUrl(call: VideoConfData, logStorage: AppLogStorage, accessors: AppAccessorManager): Promise { - return (await this.runTheCode(AppMethod._VIDEOCONF_GENERATE_URL, logStorage, accessors, [call])) as string; + public async runGenerateUrl(call: VideoConfData, logStorage: AppLogStorage): Promise { + return (await this.runTheCode(AppMethod._VIDEOCONF_GENERATE_URL, logStorage, [call])) as string; } public async runCustomizeUrl( @@ -44,35 +43,28 @@ export class AppVideoConfProvider { user: IVideoConferenceUser | undefined, options: IVideoConferenceOptions = {}, logStorage: AppLogStorage, - accessors: AppAccessorManager, ): Promise { - return (await this.runTheCode(AppMethod._VIDEOCONF_CUSTOMIZE_URL, logStorage, accessors, [call, user, options])) as string; + return (await this.runTheCode(AppMethod._VIDEOCONF_CUSTOMIZE_URL, logStorage, [call, user, options])) as string; } - public async runOnNewVideoConference(call: VideoConference, logStorage: AppLogStorage, accessors: AppAccessorManager): Promise { - await this.runTheCode(AppMethod._VIDEOCONF_NEW, logStorage, accessors, [call]); + public async runOnNewVideoConference(call: VideoConference, logStorage: AppLogStorage): Promise { + await this.runTheCode(AppMethod._VIDEOCONF_NEW, logStorage, [call]); } - public async runOnVideoConferenceChanged(call: VideoConference, logStorage: AppLogStorage, accessors: AppAccessorManager): Promise { - await this.runTheCode(AppMethod._VIDEOCONF_CHANGED, logStorage, accessors, [call]); + public async runOnVideoConferenceChanged(call: VideoConference, logStorage: AppLogStorage): Promise { + await this.runTheCode(AppMethod._VIDEOCONF_CHANGED, logStorage, [call]); } - public async runOnUserJoin( - call: VideoConference, - user: IVideoConferenceUser | undefined, - logStorage: AppLogStorage, - accessors: AppAccessorManager, - ): Promise { - await this.runTheCode(AppMethod._VIDEOCONF_USER_JOINED, logStorage, accessors, [call, user]); + public async runOnUserJoin(call: VideoConference, user: IVideoConferenceUser | undefined, logStorage: AppLogStorage): Promise { + await this.runTheCode(AppMethod._VIDEOCONF_USER_JOINED, logStorage, [call, user]); } public async runGetVideoConferenceInfo( call: VideoConference, user: IVideoConferenceUser | undefined, logStorage: AppLogStorage, - accessors: AppAccessorManager, ): Promise | undefined> { - return (await this.runTheCode(AppMethod._VIDEOCONF_GET_INFO, logStorage, accessors, [call, user])) as Array | undefined; + return (await this.runTheCode(AppMethod._VIDEOCONF_GET_INFO, logStorage, [call, user])) as Array | undefined; } private async runTheCode( @@ -85,7 +77,6 @@ export class AppVideoConfProvider { | AppMethod._VIDEOCONF_GET_INFO | AppMethod._VIDEOCONF_USER_JOINED, _logStorage: AppLogStorage, - _accessors: AppAccessorManager, runContextArgs: Array, ): Promise | undefined> { const provider = this.provider.name; diff --git a/packages/apps/src/server/managers/AppVideoConfProviderManager.ts b/packages/apps/src/server/managers/AppVideoConfProviderManager.ts index 2a3ec752dd10c..ef8596c93e0e6 100644 --- a/packages/apps/src/server/managers/AppVideoConfProviderManager.ts +++ b/packages/apps/src/server/managers/AppVideoConfProviderManager.ts @@ -11,15 +11,12 @@ import type { IVideoConferenceUser } from '@rocket.chat/apps-engine/definition/v import type { AppManager } from '../AppManager'; import type { VideoConferenceBridge } from '../bridges'; import { VideoConfProviderAlreadyExistsError, VideoConfProviderNotRegisteredError } from '../errors'; -import type { AppAccessorManager } from './AppAccessorManager'; import { AppPermissionManager } from './AppPermissionManager'; import { AppVideoConfProvider } from './AppVideoConfProvider'; import { PermissionDeniedError } from '../errors/PermissionDeniedError'; import { AppPermissions } from '../permissions/AppPermissions'; export class AppVideoConfProviderManager { - private readonly accessors: AppAccessorManager; - private readonly bridge: VideoConferenceBridge; private videoConfProviders: Map>; @@ -28,7 +25,6 @@ export class AppVideoConfProviderManager { constructor(private readonly manager: AppManager) { this.bridge = this.manager.getBridges().getVideoConferenceBridge(); - this.accessors = this.manager.getAccessorManager(); this.videoConfProviders = new Map>(); this.providerApps = new Map(); @@ -111,7 +107,7 @@ export class AppVideoConfProviderManager { throw new VideoConfProviderNotRegisteredError(providerName); } - return providerInfo.runIsFullyConfigured(this.manager.getLogStorage(), this.accessors); + return providerInfo.runIsFullyConfigured(this.manager.getLogStorage()); } public async onNewVideoConference(providerName: string, call: VideoConference): Promise { @@ -120,7 +116,7 @@ export class AppVideoConfProviderManager { throw new VideoConfProviderNotRegisteredError(providerName); } - return providerInfo.runOnNewVideoConference(call, this.manager.getLogStorage(), this.accessors); + return providerInfo.runOnNewVideoConference(call, this.manager.getLogStorage()); } public async onVideoConferenceChanged(providerName: string, call: VideoConference): Promise { @@ -129,7 +125,7 @@ export class AppVideoConfProviderManager { throw new VideoConfProviderNotRegisteredError(providerName); } - return providerInfo.runOnVideoConferenceChanged(call, this.manager.getLogStorage(), this.accessors); + return providerInfo.runOnVideoConferenceChanged(call, this.manager.getLogStorage()); } public async onUserJoin(providerName: string, call: VideoConference, user?: IVideoConferenceUser): Promise { @@ -138,7 +134,7 @@ export class AppVideoConfProviderManager { throw new VideoConfProviderNotRegisteredError(providerName); } - return providerInfo.runOnUserJoin(call, user, this.manager.getLogStorage(), this.accessors); + return providerInfo.runOnUserJoin(call, user, this.manager.getLogStorage()); } public async getVideoConferenceInfo( @@ -151,7 +147,7 @@ export class AppVideoConfProviderManager { throw new VideoConfProviderNotRegisteredError(providerName); } - return providerInfo.runGetVideoConferenceInfo(call, user, this.manager.getLogStorage(), this.accessors); + return providerInfo.runGetVideoConferenceInfo(call, user, this.manager.getLogStorage()); } public async generateUrl(providerName: string, call: VideoConfData): Promise { @@ -160,7 +156,7 @@ export class AppVideoConfProviderManager { throw new VideoConfProviderNotRegisteredError(providerName); } - return providerInfo.runGenerateUrl(call, this.manager.getLogStorage(), this.accessors); + return providerInfo.runGenerateUrl(call, this.manager.getLogStorage()); } public async customizeUrl( @@ -174,7 +170,7 @@ export class AppVideoConfProviderManager { throw new VideoConfProviderNotRegisteredError(providerName); } - return providerInfo.runCustomizeUrl(call, user, options, this.manager.getLogStorage(), this.accessors); + return providerInfo.runCustomizeUrl(call, user, options, this.manager.getLogStorage()); } private retrieveProviderInfo(providerName: string): AppVideoConfProvider | undefined { diff --git a/packages/apps/src/server/managers/index.ts b/packages/apps/src/server/managers/index.ts index 9d7b22c79bc53..c467f6c24d9a6 100644 --- a/packages/apps/src/server/managers/index.ts +++ b/packages/apps/src/server/managers/index.ts @@ -1,4 +1,3 @@ -import { AppAccessorManager } from './AppAccessorManager'; import { AppApiManager } from './AppApiManager'; import { AppExternalComponentManager } from './AppExternalComponentManager'; import { AppLicenseManager } from './AppLicenseManager'; @@ -10,7 +9,6 @@ import { AppSlashCommandManager } from './AppSlashCommandManager'; import { AppVideoConfProviderManager } from './AppVideoConfProviderManager'; export { - AppAccessorManager, AppLicenseManager, AppListenerManager, AppExternalComponentManager, diff --git a/packages/apps/src/server/misc/UIHelper.ts b/packages/apps/src/server/misc/UIHelper.ts deleted file mode 100644 index acfe6d1ffea0c..0000000000000 --- a/packages/apps/src/server/misc/UIHelper.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { randomUUID } from 'node:crypto'; - -import type { IBlock } from '@rocket.chat/apps-engine/definition/uikit'; -import type { LayoutBlock } from '@rocket.chat/ui-kit'; - -export class UIHelper { - /** - * Assign blockId, appId and actionId to every block/element inside the array - * @param blocks the blocks that will be iterated and assigned the ids - * @param appId the appId that will be assigned to - * @returns the array of block with the ids properties assigned - */ - public static assignIds(blocks: Array, appId: string): Array { - blocks.forEach((block: (IBlock | LayoutBlock) & { appId?: string; blockId?: string; elements?: Array }) => { - if (!block.appId) { - block.appId = appId; - } - if (!block.blockId) { - block.blockId = randomUUID(); - } - if (block.elements) { - block.elements.forEach((element) => { - if (!element.actionId) { - element.actionId = randomUUID(); - } - }); - } - }); - - return blocks; - } -} diff --git a/packages/apps/tests/server/AppManager.test.ts b/packages/apps/tests/server/AppManager.test.ts index f4b7db974e9c3..18cb65f5f0362 100644 --- a/packages/apps/tests/server/AppManager.test.ts +++ b/packages/apps/tests/server/AppManager.test.ts @@ -5,7 +5,6 @@ import { AppManager } from '../../src/server/AppManager'; import { AppBridges } from '../../src/server/bridges'; import { AppCompiler, AppPackageParser } from '../../src/server/compiler'; import { - AppAccessorManager, AppApiManager, AppExternalComponentManager, AppListenerManager, @@ -131,7 +130,6 @@ describe('AppManager', () => { assert.ok(manager.getParser() instanceof AppPackageParser); assert.ok(manager.getCompiler() instanceof AppCompiler); - assert.ok(manager.getAccessorManager() instanceof AppAccessorManager); assert.ok(manager.getBridges() instanceof AppBridges); assert.ok(manager.getListenerManager() instanceof AppListenerManager); assert.ok(manager.getCommandManager() instanceof AppSlashCommandManager); diff --git a/packages/apps/tests/server/accessors/AppAccessors.test.ts b/packages/apps/tests/server/accessors/AppAccessors.test.ts deleted file mode 100644 index 9cd414de009fa..0000000000000 --- a/packages/apps/tests/server/accessors/AppAccessors.test.ts +++ /dev/null @@ -1,121 +0,0 @@ -import * as assert from 'node:assert'; -import { afterEach, beforeEach, describe, it, mock } from 'node:test'; - -import { AppStatus } from '@rocket.chat/apps-engine/definition/AppStatus'; -import type { AppMethod } from '@rocket.chat/apps-engine/definition/metadata'; - -import type { AppManager } from '../../../src/server/AppManager'; -import type { ProxiedApp } from '../../../src/server/ProxiedApp'; -import { AppAccessors } from '../../../src/server/accessors'; -import type { AppBridges } from '../../../src/server/bridges'; -import { AppConsole } from '../../../src/server/logging'; -import type { - AppExternalComponentManager, - AppSchedulerManager, - AppSettingsManager, - AppSlashCommandManager, - AppVideoConfProviderManager, -} from '../../../src/server/managers'; -import { AppAccessorManager, AppApiManager } from '../../../src/server/managers'; -import type { AppOutboundCommunicationProviderManager } from '../../../src/server/managers/AppOutboundCommunicationProviderManager'; -import type { UIActionButtonManager } from '../../../src/server/managers/UIActionButtonManager'; -import type { AppsEngineRuntime } from '../../../src/server/runtime/AppsEngineRuntime'; -import type { AppLogStorage } from '../../../src/server/storage'; -import { TestsAppBridges } from '../../test-data/bridges/appBridges'; -import { TestsAppLogStorage } from '../../test-data/storage/logStorage'; -import { TestData } from '../../test-data/utilities'; - -describe('AppAccessors', () => { - let mockBridges: TestsAppBridges; - let mockApp: ProxiedApp; - let mockAccessors: AppAccessorManager; - let mockManager: AppManager; - let mockApiManager: AppApiManager; - - beforeEach(() => { - mockBridges = new TestsAppBridges(); - - mockApp = { - getRuntime() { - return {} as AppsEngineRuntime; - }, - getID() { - return 'testing'; - }, - getStatus() { - return Promise.resolve(AppStatus.AUTO_ENABLED); - }, - setupLogger(method: AppMethod): AppConsole { - return new AppConsole(method); - }, - } as ProxiedApp; - - const bri = mockBridges; - const app = mockApp; - mockManager = { - getBridges(): AppBridges { - return bri; - }, - getCommandManager() { - return {} as AppSlashCommandManager; - }, - getExternalComponentManager() { - return {} as AppExternalComponentManager; - }, - getOneById(appId: string): ProxiedApp { - return appId === 'failMePlease' ? undefined : app; - }, - getLogStorage(): AppLogStorage { - return new TestsAppLogStorage(); - }, - getSchedulerManager() { - return {} as AppSchedulerManager; - }, - getUIActionButtonManager() { - return {} as UIActionButtonManager; - }, - getVideoConfProviderManager() { - return {} as AppVideoConfProviderManager; - }, - getSettingsManager() { - return {} as AppSettingsManager; - }, - getOutboundCommunicationProviderManager() { - return {} as AppOutboundCommunicationProviderManager; - }, - } as unknown as AppManager; - - mockAccessors = new AppAccessorManager(mockManager); - const ac = mockAccessors; - mockManager.getAccessorManager = function _getAccessorManager(): AppAccessorManager { - return ac; - }; - - mockApiManager = new AppApiManager(mockManager); - const apiManager = mockApiManager; - mockManager.getApiManager = function _getApiManager(): AppApiManager { - return apiManager; - }; - }); - - afterEach(() => { - mock.restoreAll(); - }); - - it('testAppAccessor', () => { - assert.throws(() => new AppAccessors({} as AppManager, '')); - assert.doesNotThrow(() => new AppAccessors(mockManager, 'testing')); - - const appAccessors = new AppAccessors(mockManager, 'testing'); - - assert.deepStrictEqual(appAccessors.environmentReader, mockAccessors.getEnvironmentRead('testing')); - assert.deepStrictEqual(appAccessors.environmentWriter, mockAccessors.getEnvironmentWrite('testing')); - assert.deepStrictEqual(appAccessors.reader, mockAccessors.getReader('testing')); - assert.deepStrictEqual(appAccessors.http, mockAccessors.getHttp('testing')); - assert.deepStrictEqual(appAccessors.providedApiEndpoints, mockApiManager.listApis('testing')); - - mockApiManager.addApi('testing', TestData.getApi('app-accessor-api')); - - assert.deepStrictEqual(appAccessors.providedApiEndpoints, mockApiManager.listApis('testing')); - }); -}); diff --git a/packages/apps/tests/server/accessors/ConfigurationExtend.test.ts b/packages/apps/tests/server/accessors/ConfigurationExtend.test.ts deleted file mode 100644 index fda3204f9d0c4..0000000000000 --- a/packages/apps/tests/server/accessors/ConfigurationExtend.test.ts +++ /dev/null @@ -1,56 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { - IApiExtend, - IExternalComponentsExtend, - IHttpExtend, - IOutboundCommunicationProviderExtend, - ISchedulerExtend, - ISettingsExtend, - ISlashCommandsExtend, - IUIExtend, - IVideoConfProvidersExtend, -} from '@rocket.chat/apps-engine/definition/accessors'; - -import { ConfigurationExtend } from '../../../src/server/accessors'; - -describe('ConfigurationExtend', () => { - it('useConfigurationExtend', () => { - const he = {} as IHttpExtend; - const se = {} as ISettingsExtend; - const sce = {} as ISlashCommandsExtend; - const api = {} as IApiExtend; - const externalComponent = {} as IExternalComponentsExtend; - const schedulerExtend = {} as ISchedulerExtend; - const uiExtend = {} as IUIExtend; - const vcProvidersExtend = {} as IVideoConfProvidersExtend; - const outboundCommunication = {} as IOutboundCommunicationProviderExtend; - - assert.doesNotThrow( - () => - new ConfigurationExtend(he, se, sce, api, externalComponent, schedulerExtend, uiExtend, vcProvidersExtend, outboundCommunication), - ); - - const ce = new ConfigurationExtend( - he, - se, - sce, - api, - externalComponent, - schedulerExtend, - uiExtend, - vcProvidersExtend, - outboundCommunication, - ); - assert.ok(ce.http !== undefined); - assert.ok(ce.settings !== undefined); - assert.ok(ce.slashCommands !== undefined); - assert.ok(ce.api !== undefined); - assert.ok(ce.externalComponents !== undefined); - assert.ok(ce.scheduler !== undefined); - assert.ok(ce.ui !== undefined); - assert.ok(ce.videoConfProviders !== undefined); - assert.ok(ce.outboundCommunication !== undefined); - }); -}); diff --git a/packages/apps/tests/server/accessors/ConfigurationModify.test.ts b/packages/apps/tests/server/accessors/ConfigurationModify.test.ts deleted file mode 100644 index 96d8439638d7f..0000000000000 --- a/packages/apps/tests/server/accessors/ConfigurationModify.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it, beforeEach } from 'node:test'; - -import type { ISchedulerModify, IServerSettingsModify, ISlashCommandsModify } from '@rocket.chat/apps-engine/definition/accessors'; - -import { ConfigurationModify } from '../../../src/server/accessors'; - -describe('ConfigurationModify', () => { - let ssm: IServerSettingsModify; - let scm: ISlashCommandsModify; - let scheduler: ISchedulerModify; - - beforeEach(() => { - ssm = {} as IServerSettingsModify; - scm = {} as ISlashCommandsModify; - scheduler = {} as ISchedulerModify; - }); - - it('useConfigurationModify', () => { - assert.doesNotThrow(() => new ConfigurationModify(ssm, scm, scheduler)); - - const sm = new ConfigurationModify(ssm, scm, scheduler); - assert.strictEqual(sm.serverSettings, ssm); - assert.strictEqual(sm.slashCommands, scm); - assert.strictEqual(sm.scheduler, scheduler); - }); -}); diff --git a/packages/apps/tests/server/accessors/EnvironmentRead.test.ts b/packages/apps/tests/server/accessors/EnvironmentRead.test.ts deleted file mode 100644 index df41ac7a72989..0000000000000 --- a/packages/apps/tests/server/accessors/EnvironmentRead.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { IEnvironmentalVariableRead, IServerSettingRead, ISettingRead } from '@rocket.chat/apps-engine/definition/accessors'; - -import { EnvironmentRead } from '../../../src/server/accessors'; - -describe('EnvironmentRead', () => { - it('useEnvironmentRead', () => { - const evr = {} as IEnvironmentalVariableRead; - const ssr = {} as IServerSettingRead; - const sr = {} as ISettingRead; - - assert.doesNotThrow(() => new EnvironmentRead(sr, ssr, evr)); - - const er = new EnvironmentRead(sr, ssr, evr); - assert.ok(er.getSettings() !== undefined); - assert.ok(er.getServerSettings() !== undefined); - assert.ok(er.getEnvironmentVariables() !== undefined); - }); -}); diff --git a/packages/apps/tests/server/accessors/EnvironmentWrite.test.ts b/packages/apps/tests/server/accessors/EnvironmentWrite.test.ts deleted file mode 100644 index b7f2ce4ae8d78..0000000000000 --- a/packages/apps/tests/server/accessors/EnvironmentWrite.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { IServerSettingUpdater, ISettingUpdater } from '@rocket.chat/apps-engine/definition/accessors'; - -import { EnvironmentWrite } from '../../../src/server/accessors'; - -describe('EnvironmentWrite', () => { - it('useEnvironmentWrite', () => { - const sr = {} as ISettingUpdater; - const serverSettings = {} as IServerSettingUpdater; - - assert.doesNotThrow(() => new EnvironmentWrite(sr, serverSettings)); - - const er = new EnvironmentWrite(sr, serverSettings); - assert.ok(er.getSettings() !== undefined); - assert.ok(er.getServerSettings() !== undefined); - }); -}); diff --git a/packages/apps/tests/server/accessors/EnvironmentalVariableRead.test.ts b/packages/apps/tests/server/accessors/EnvironmentalVariableRead.test.ts deleted file mode 100644 index 423a6ff9036f4..0000000000000 --- a/packages/apps/tests/server/accessors/EnvironmentalVariableRead.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import { EnvironmentalVariableRead } from '../../../src/server/accessors'; -import type { EnvironmentalVariableBridge } from '../../../src/server/bridges'; - -describe('EnvironmentalVariableRead', () => { - it('useEnvironmentalVariableRead', async () => { - const mockEnvVarBridge = { - doGetValueByName(name: string, appId: string): Promise { - return Promise.resolve('value'); - }, - doIsReadable(name: string, appId: string): Promise { - return Promise.resolve(true); - }, - doIsSet(name: string, appId: string): Promise { - return Promise.resolve(false); - }, - } as EnvironmentalVariableBridge; - - assert.doesNotThrow(() => new EnvironmentalVariableRead(mockEnvVarBridge, 'testing')); - - const evr = new EnvironmentalVariableRead(mockEnvVarBridge, 'testing'); - assert.strictEqual(await evr.getValueByName('testing'), 'value'); - assert.ok(await evr.isReadable('testing')); - assert.ok(!(await evr.isSet('testing2'))); - }); -}); diff --git a/packages/apps/tests/server/accessors/Http.test.ts b/packages/apps/tests/server/accessors/Http.test.ts deleted file mode 100644 index 69d5ffd94afdb..0000000000000 --- a/packages/apps/tests/server/accessors/Http.test.ts +++ /dev/null @@ -1,155 +0,0 @@ -import * as assert from 'node:assert'; -import { afterEach, beforeEach, describe, it, mock } from 'node:test'; - -import type { - IHttpExtend, - IHttpPreRequestHandler, - IHttpPreResponseHandler, - IHttpRequest, - IHttpResponse, - IPersistence, - IRead, -} from '@rocket.chat/apps-engine/definition/accessors'; - -import { Http, HttpExtend } from '../../../src/server/accessors'; -import type { AppBridges, HttpBridge, IHttpBridgeRequestInfo } from '../../../src/server/bridges'; -import type { AppAccessorManager } from '../../../src/server/managers'; - -describe('Http', () => { - let mockAppId: string; - let mockHttpBridge: HttpBridge; - let mockAppBridge: AppBridges; - let mockHttpExtender: IHttpExtend; - let mockReader: IRead; - let mockPersis: IPersistence; - let mockAccessorManager: AppAccessorManager; - let mockPreRequestHandler: IHttpPreRequestHandler; - let mockPreResponseHandler: IHttpPreResponseHandler; - let mockResponse: IHttpResponse; - - beforeEach(() => { - mockAppId = 'testing-app'; - - mockResponse = { statusCode: 200 } as IHttpResponse; - const res = mockResponse; - mockHttpBridge = { - doCall(info: IHttpBridgeRequestInfo): Promise { - return Promise.resolve(res); - }, - } as HttpBridge; - - const httpBridge = mockHttpBridge; - mockAppBridge = { - getHttpBridge(): HttpBridge { - return httpBridge; - }, - } as AppBridges; - - mockHttpExtender = new HttpExtend(); - - mockReader = {} as IRead; - mockPersis = {} as IPersistence; - const reader = mockReader; - const persis = mockPersis; - mockAccessorManager = { - getReader(appId: string): IRead { - return reader; - }, - getPersistence(appId: string): IPersistence { - return persis; - }, - } as AppAccessorManager; - - mockPreRequestHandler = { - executePreHttpRequest(url: string, request: IHttpRequest, read: IRead, persistence: IPersistence): Promise { - return Promise.resolve(request); - }, - } as IHttpPreRequestHandler; - - mockPreResponseHandler = { - executePreHttpResponse(response: IHttpResponse, read: IRead, persistence: IPersistence): Promise { - return Promise.resolve(response); - }, - } as IHttpPreResponseHandler; - }); - - afterEach(() => { - mock.restoreAll(); - }); - - it('useHttp', async () => { - assert.doesNotThrow(() => new Http(mockAccessorManager, mockAppBridge, mockHttpExtender, mockAppId)); - - const http = new Http(mockAccessorManager, mockAppBridge, mockHttpExtender, mockAppId); - - const doCallSpy = mock.method(mockHttpBridge, 'doCall'); - const preRequestSpy = mock.method(mockPreRequestHandler, 'executePreHttpRequest'); - const preResponseSpy = mock.method(mockPreResponseHandler, 'executePreHttpResponse'); - - assert.ok((await http.get('url-here')) !== undefined); - assert.ok((await http.post('url-here')) !== undefined); - assert.ok((await http.put('url-here')) !== undefined); - assert.ok((await http.del('url-here')) !== undefined); - assert.ok((await http.get('url-here', { headers: {}, params: {} })) !== undefined); - - const request1 = {} as IHttpRequest; - mockHttpExtender.provideDefaultHeader('Auth-Token', 'Bearer asdfasdf'); - assert.ok((await http.post('url-here', request1)) !== undefined); - assert.strictEqual(request1.headers['Auth-Token'], 'Bearer asdfasdf'); - request1.headers['Auth-Token'] = 'mine'; - assert.ok((await http.put('url-here', request1)) !== undefined); // Check that the default doesn't override provided - assert.strictEqual(request1.headers['Auth-Token'], 'mine'); - - const request2 = {} as IHttpRequest; - mockHttpExtender.provideDefaultParam('count', '20'); - assert.ok((await http.del('url-here', request2)) !== undefined); - assert.strictEqual(request2.params.count, '20'); - request2.params.count = '50'; - assert.ok((await http.get('url-here', request2)) !== undefined); // Check that the default doesn't override provided - assert.strictEqual(request2.params.count, '50'); - - mockHttpExtender.providePreRequestHandler(mockPreRequestHandler); - const request3 = {} as IHttpRequest; - assert.ok((await http.post('url-here', request3)) !== undefined); - assert.strictEqual(preRequestSpy.mock.calls.length, 1); - assert.deepStrictEqual(preRequestSpy.mock.calls[0].arguments, ['url-here', request3, mockReader, mockPersis]); - (mockHttpExtender as any).requests = []; - - mockHttpExtender.providePreResponseHandler(mockPreResponseHandler); - assert.ok((await http.post('url-here')) !== undefined); - assert.strictEqual(preResponseSpy.mock.calls.length, 1); - assert.deepStrictEqual(preResponseSpy.mock.calls[0].arguments, [mockResponse, mockReader, mockPersis]); - - assert.strictEqual(doCallSpy.mock.calls.length, 11); - }); - - it('ssrfValidationOption', async () => { - const http = new Http(mockAccessorManager, mockAppBridge, mockHttpExtender, mockAppId); - - let capturedInfo: IHttpBridgeRequestInfo | undefined; - - // Override doCall to capture the info parameter - const originalDoCall = mockHttpBridge.doCall.bind(mockHttpBridge); - mockHttpBridge.doCall = async (info: IHttpBridgeRequestInfo) => { - capturedInfo = info; - return originalDoCall(info); - }; - - // Test with ssrfValidation enabled - await http.get('url-here', { ssrfValidation: true }); - assert.ok(capturedInfo !== undefined); - assert.strictEqual(capturedInfo!.request.ssrfValidation, true); - - // Test with ssrfValidation disabled - await http.post('url-here', { ssrfValidation: false }); - assert.strictEqual(capturedInfo!.request.ssrfValidation, false); - - // Test with ssrfValidation undefined (default) - await http.put('url-here', {}); - assert.strictEqual(capturedInfo!.request.ssrfValidation, undefined); - - // Test with no options - await http.del('url-here'); - assert.strictEqual(capturedInfo!.request.ssrfValidation, undefined); - }); -}); diff --git a/packages/apps/tests/server/accessors/HttpExtend.test.ts b/packages/apps/tests/server/accessors/HttpExtend.test.ts deleted file mode 100644 index 4f80e69e13924..0000000000000 --- a/packages/apps/tests/server/accessors/HttpExtend.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { IHttpPreRequestHandler, IHttpPreResponseHandler } from '@rocket.chat/apps-engine/definition/accessors'; - -import { HttpExtend } from '../../../src/server/accessors'; - -describe('HttpExtend', () => { - it('basicHttpExtend', () => { - assert.doesNotThrow(() => new HttpExtend()); - - const he = new HttpExtend(); - assert.deepStrictEqual(he.getDefaultHeaders(), new Map()); - assert.deepStrictEqual(he.getDefaultParams(), new Map()); - assert.strictEqual(he.getPreRequestHandlers().length, 0); - assert.strictEqual(he.getPreResponseHandlers().length, 0); - }); - - it('defaultHeadersInHttpExtend', () => { - const he = new HttpExtend(); - - assert.doesNotThrow(() => he.provideDefaultHeader('Auth', 'token')); - assert.strictEqual(he.getDefaultHeaders().size, 1); - assert.strictEqual(he.getDefaultHeaders().get('Auth'), 'token'); - - assert.doesNotThrow(() => - he.provideDefaultHeaders({ - Auth: 'token2', - Another: 'thing', - }), - ); - assert.strictEqual(he.getDefaultHeaders().size, 2); - assert.strictEqual(he.getDefaultHeaders().get('Auth'), 'token2'); - assert.strictEqual(he.getDefaultHeaders().get('Another'), 'thing'); - }); - - it('defaultParamsInHttpExtend', () => { - const he = new HttpExtend(); - - assert.doesNotThrow(() => he.provideDefaultParam('id', 'abcdefg')); - assert.strictEqual(he.getDefaultParams().size, 1); - assert.strictEqual(he.getDefaultParams().get('id'), 'abcdefg'); - - assert.doesNotThrow(() => - he.provideDefaultParams({ - id: 'zyxwvu', - count: '4', - }), - ); - assert.strictEqual(he.getDefaultParams().size, 2); - assert.strictEqual(he.getDefaultParams().get('id'), 'zyxwvu'); - assert.strictEqual(he.getDefaultParams().get('count'), '4'); - }); - - it('preRequestHandlersInHttpExtend', () => { - const he = new HttpExtend(); - - const preRequestHandler: IHttpPreRequestHandler = { - executePreHttpRequest: function _thing(url, req) { - return new Promise((resolve) => resolve(req)); - }, - }; - - assert.doesNotThrow(() => he.providePreRequestHandler(preRequestHandler)); - assert.ok(he.getPreRequestHandlers().length > 0); - }); - - it('preResponseHandlersInHttpExtend', () => { - const he = new HttpExtend(); - - const preResponseHandler: IHttpPreResponseHandler = { - executePreHttpResponse: function _thing(res) { - return new Promise((resolve) => resolve(res)); - }, - }; - - assert.doesNotThrow(() => he.providePreResponseHandler(preResponseHandler)); - assert.ok(he.getPreResponseHandlers().length > 0); - }); -}); diff --git a/packages/apps/tests/server/accessors/MessageBuilder.test.ts b/packages/apps/tests/server/accessors/MessageBuilder.test.ts deleted file mode 100644 index e73d04b856874..0000000000000 --- a/packages/apps/tests/server/accessors/MessageBuilder.test.ts +++ /dev/null @@ -1,134 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { IMessage } from '@rocket.chat/apps-engine/definition/messages'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import { MessageBuilder, UserBuilder } from '../../../src/server/accessors'; -import { TestData } from '../../test-data/utilities'; - -describe('MessageBuilder', () => { - it('basicMessageBuilder', () => { - assert.doesNotThrow(() => new MessageBuilder()); - assert.doesNotThrow(() => new MessageBuilder(TestData.getMessage())); - }); - - it('settingOnMessageBuilder', () => { - const mbOnce = new MessageBuilder(); - - // setData just replaces the passed in object, so let's treat it differently - assert.strictEqual(mbOnce.setData({ text: 'hello' } as IMessage), mbOnce); - assert.strictEqual((mbOnce as any).msg.text, 'hello'); - - const mbUpdate = new MessageBuilder(); - const editor = new UserBuilder(); - editor.setUsername('username'); - editor.setDisplayName('name'); - - // setUpdateData keeps the ID passed in the message object, so let's treat it differently - assert.strictEqual(mbUpdate.setUpdateData({ text: 'hello', id: 'messageID' } as IMessage, editor.getUser() as IUser), mbUpdate); - assert.strictEqual((mbUpdate as any).msg.text, 'hello'); - assert.strictEqual((mbUpdate as any).msg.id, 'messageID'); - - const msg: IMessage = {} as IMessage; - const mb = new MessageBuilder(msg); - - assert.strictEqual(mb.setThreadId('a random thread id'), mb); - assert.strictEqual(msg.threadId, 'a random thread id'); - assert.strictEqual(mb.getThreadId(), 'a random thread id'); - - const room = TestData.getRoom(); - assert.strictEqual(mb.setRoom(room), mb); - assert.deepStrictEqual(msg.room, room); - assert.deepStrictEqual(mb.getRoom(), room); - - const sender = TestData.getUser(); - assert.strictEqual(mb.setSender(sender), mb); - assert.deepStrictEqual(msg.sender, sender); - assert.deepStrictEqual(mb.getSender(), sender); - - assert.strictEqual(mb.setText('testing, yo!'), mb); - assert.deepStrictEqual(msg.text, 'testing, yo!'); - assert.deepStrictEqual(mb.getText(), 'testing, yo!'); - - assert.strictEqual(mb.setEmojiAvatar(':ghost:'), mb); - assert.deepStrictEqual(msg.emoji, ':ghost:'); - assert.deepStrictEqual(mb.getEmojiAvatar(), ':ghost:'); - - assert.strictEqual(mb.setAvatarUrl('https://rocket.chat/'), mb); - assert.deepStrictEqual(msg.avatarUrl, 'https://rocket.chat/'); - assert.deepStrictEqual(mb.getAvatarUrl(), 'https://rocket.chat/'); - - assert.strictEqual(mb.setUsernameAlias('Some Bot'), mb); - assert.deepStrictEqual(msg.alias, 'Some Bot'); - assert.deepStrictEqual(mb.getUsernameAlias(), 'Some Bot'); - - assert.strictEqual(msg.attachments, undefined); - assert.strictEqual(mb.getAttachments(), undefined); - assert.strictEqual(mb.addAttachment({ color: '#0ff' }), mb); - assert.ok(msg.attachments !== undefined); - assert.ok(mb.getAttachments() !== undefined); - assert.ok(msg.attachments.length > 0); - assert.ok(mb.getAttachments().length > 0); - - assert.deepStrictEqual(msg.attachments[0].color, '#0ff'); - assert.deepStrictEqual(mb.getAttachments()[0].color, '#0ff'); - - assert.strictEqual(mb.setAttachments([]), mb); - assert.strictEqual(msg.attachments.length, 0); - assert.strictEqual(mb.getAttachments().length, 0); - - delete msg.attachments; - assert.throws(() => mb.replaceAttachment(1, {}), { name: 'Error', message: 'No attachment found at the index of "1" to replace.' }); - assert.strictEqual(mb.addAttachment({}), mb); - assert.strictEqual(mb.replaceAttachment(0, { color: '#f0f' }), mb); - assert.deepStrictEqual(msg.attachments[0].color, '#f0f'); - assert.deepStrictEqual(mb.getAttachments()[0].color, '#f0f'); - - assert.strictEqual(mb.removeAttachment(0), mb); - assert.strictEqual(msg.attachments.length, 0); - assert.strictEqual(mb.getAttachments().length, 0); - - delete msg.attachments; - assert.throws(() => mb.removeAttachment(4), { name: 'Error', message: 'No attachment found at the index of "4" to remove.' }); - - const msgEditor = TestData.getUser('msg-editor-id'); - assert.strictEqual(mb.setEditor(msgEditor), mb); - assert.ok(msg.editor !== undefined); - assert.ok(mb.getEditor() !== undefined); - assert.deepStrictEqual(msg.editor.id, 'msg-editor-id'); - assert.deepStrictEqual(mb.getEditor().id, 'msg-editor-id'); - - assert.strictEqual(mb.getMessage(), msg); - delete msg.room; - assert.throws(() => mb.getMessage(), { name: 'Error', message: 'The "room" property is required.' }); - - assert.strictEqual(mb.setGroupable(true), mb); - assert.deepStrictEqual(msg.groupable, true); - assert.deepStrictEqual(mb.getGroupable(), true); - - assert.strictEqual(mb.setGroupable(false), mb); - assert.deepStrictEqual(msg.groupable, false); - assert.deepStrictEqual(mb.getGroupable(), false); - - assert.strictEqual(mb.setParseUrls(true), mb); - assert.deepStrictEqual(msg.parseUrls, true); - assert.deepStrictEqual(mb.getParseUrls(), true); - - assert.strictEqual(mb.setParseUrls(false), mb); - assert.deepStrictEqual(msg.parseUrls, false); - assert.deepStrictEqual(mb.getParseUrls(), false); - - assert.strictEqual(mb.addCustomField('thing', 'value'), mb); - assert.ok(msg.customFields !== undefined); - assert.strictEqual(msg.customFields.thing, 'value'); - assert.throws(() => mb.addCustomField('thing', 'second'), { - name: 'Error', - message: 'The message already contains a custom field by the key: thing', - }); - assert.throws(() => mb.addCustomField('thing.', 'second'), { - name: 'Error', - message: 'The given key contains a period, which is not allowed. Key: thing.', - }); - }); -}); diff --git a/packages/apps/tests/server/accessors/MessageExtender.test.ts b/packages/apps/tests/server/accessors/MessageExtender.test.ts deleted file mode 100644 index 2031e41598b1d..0000000000000 --- a/packages/apps/tests/server/accessors/MessageExtender.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { IMessage } from '@rocket.chat/apps-engine/definition/messages'; - -import { MessageExtender } from '../../../src/server/accessors'; -import { TestData } from '../../test-data/utilities'; - -describe('MessageExtender', () => { - it('basicMessageExtender', () => { - assert.doesNotThrow(() => new MessageExtender({} as IMessage)); - assert.doesNotThrow(() => new MessageExtender(TestData.getMessage())); - }); - - it('usingMessageExtender', () => { - const msg: IMessage = {} as IMessage; - const me = new MessageExtender(msg); - - assert.ok(msg.attachments !== undefined); - assert.strictEqual(msg.attachments.length, 0); - assert.strictEqual(me.addCustomField('thing', 'value'), me); - assert.ok(msg.customFields !== undefined); - assert.strictEqual(msg.customFields.thing, 'value'); - assert.throws(() => me.addCustomField('thing', 'second'), { - name: 'Error', - message: 'The message already contains a custom field by the key: thing', - }); - assert.throws(() => me.addCustomField('thing.', 'second'), { - name: 'Error', - message: 'The given key contains a period, which is not allowed. Key: thing.', - }); - - assert.strictEqual(me.addAttachment({}), me); - assert.strictEqual(msg.attachments.length, 1); - assert.strictEqual(me.addAttachments([{ collapsed: true }, { color: '#f00' }]), me); - assert.strictEqual(msg.attachments.length, 3); - - assert.notStrictEqual(me.getMessage(), msg); - assert.deepStrictEqual(me.getMessage(), msg); - }); -}); diff --git a/packages/apps/tests/server/accessors/MessageRead.test.ts b/packages/apps/tests/server/accessors/MessageRead.test.ts deleted file mode 100644 index 30ab6affa4df6..0000000000000 --- a/packages/apps/tests/server/accessors/MessageRead.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { IMessage } from '@rocket.chat/apps-engine/definition/messages'; - -import { MessageRead } from '../../../src/server/accessors'; -import type { MessageBridge } from '../../../src/server/bridges'; -import { TestData } from '../../test-data/utilities'; - -describe('MessageRead', () => { - const msg = TestData.getMessage(); - - const mockMsgBridgeWithMsg = { - doGetById(id: string, appId: string): Promise { - return Promise.resolve(msg); - }, - } as MessageBridge; - - const mockMsgBridgeNoMsg = { - doGetById(id: string, appId: string) { - return Promise.resolve(undefined); - }, - } as MessageBridge; - - it('expectDataFromMessageRead', async () => { - assert.doesNotThrow(() => new MessageRead(mockMsgBridgeWithMsg, 'testing-app')); - - const mr = new MessageRead(mockMsgBridgeWithMsg, 'testing-app'); - - assert.ok((await mr.getById('fake')) !== undefined); - assert.deepStrictEqual(await mr.getById('fake'), msg); - - assert.ok((await mr.getSenderUser('fake')) !== undefined); - assert.deepStrictEqual(await mr.getSenderUser('fake'), msg.sender); - - assert.ok((await mr.getRoom('fake')) !== undefined); - assert.deepStrictEqual(await mr.getRoom('fake'), msg.room); - }); - - it('doNotExpectDataFromMessageRead', async () => { - assert.doesNotThrow(() => new MessageRead(mockMsgBridgeNoMsg, 'testing')); - - const nomr = new MessageRead(mockMsgBridgeNoMsg, 'testing'); - assert.strictEqual(await nomr.getById('fake'), undefined); - assert.strictEqual(await nomr.getSenderUser('fake'), undefined); - assert.strictEqual(await nomr.getRoom('fake'), undefined); - }); -}); diff --git a/packages/apps/tests/server/accessors/Modify.test.ts b/packages/apps/tests/server/accessors/Modify.test.ts deleted file mode 100644 index 982c48419d39f..0000000000000 --- a/packages/apps/tests/server/accessors/Modify.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import { Modify } from '../../../src/server/accessors'; -import type { - AppBridges, - MessageBridge, - ModerationBridge, - SchedulerBridge, - UiInteractionBridge, - UserBridge, -} from '../../../src/server/bridges'; -import type { OAuthAppsBridge } from '../../../src/server/bridges/OAuthAppsBridge'; - -describe('Modify', () => { - it('useModify', () => { - const mockAppBridges = { - getUserBridge(): UserBridge { - return {} as UserBridge; - }, - getMessageBridge(): MessageBridge { - return {} as MessageBridge; - }, - getUiInteractionBridge(): UiInteractionBridge { - return {} as UiInteractionBridge; - }, - getSchedulerBridge() { - return {} as SchedulerBridge; - }, - getOAuthAppsBridge() { - return {} as OAuthAppsBridge; - }, - getModerationBridge() { - return {} as ModerationBridge; - }, - } as AppBridges; - - assert.doesNotThrow(() => new Modify(mockAppBridges, 'testing')); - - const md = new Modify(mockAppBridges, 'testing'); - assert.ok(md.getCreator() !== undefined); - assert.ok(md.getExtender() !== undefined); - assert.ok(md.getNotifier() !== undefined); - assert.ok(md.getUpdater() !== undefined); - }); -}); diff --git a/packages/apps/tests/server/accessors/ModifyCreator.test.ts b/packages/apps/tests/server/accessors/ModifyCreator.test.ts deleted file mode 100644 index ea3d49c15894b..0000000000000 --- a/packages/apps/tests/server/accessors/ModifyCreator.test.ts +++ /dev/null @@ -1,130 +0,0 @@ -import * as assert from 'node:assert'; -import { afterEach, beforeEach, describe, it, mock } from 'node:test'; - -import type { IMessage } from '@rocket.chat/apps-engine/definition/messages'; -import type { IRoom } from '@rocket.chat/apps-engine/definition/rooms'; -import { RoomType } from '@rocket.chat/apps-engine/definition/rooms'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; -import { UserStatusConnection, UserType } from '@rocket.chat/apps-engine/definition/users'; - -import { ModifyCreator } from '../../../src/server/accessors'; -import type { AppBridges, MessageBridge, RoomBridge, UserBridge } from '../../../src/server/bridges'; -import { TestData } from '../../test-data/utilities'; - -describe('ModifyCreator', () => { - let mockAppId: string; - let mockRoomBridge: RoomBridge; - let mockMessageBridge: MessageBridge; - let mockAppBridge: AppBridges; - let mockAppUser: IUser; - let mockUserBridge: UserBridge; - - beforeEach(() => { - mockAppId = 'testing-app'; - - mockAppUser = { - id: 'mockAppUser', - isEnabled: true, - name: 'mockAppUser', - roles: ['app'], - status: 'online', - statusConnection: UserStatusConnection.UNDEFINED, - type: UserType.APP, - username: 'mockAppUser', - emails: [], - utcOffset: -5, - createdAt: new Date(), - updatedAt: new Date(), - lastLoginAt: new Date(), - }; - - mockRoomBridge = { - doCreate(room: IRoom, members: Array, appId: string): Promise { - return Promise.resolve('roomId'); - }, - } as RoomBridge; - - mockMessageBridge = { - doCreate(msg: IMessage, appId: string): Promise { - return Promise.resolve('msgId'); - }, - } as MessageBridge; - - const appUser = mockAppUser; - mockUserBridge = { - doGetAppUser: (appId: string) => { - return Promise.resolve(appUser); - }, - } as UserBridge; - - const msgBridge = mockMessageBridge; - const rmBridge = mockRoomBridge; - const userBridge = mockUserBridge; - mockAppBridge = { - getMessageBridge: () => msgBridge, - getRoomBridge: () => rmBridge, - getUserBridge: () => userBridge, - } as AppBridges; - }); - - afterEach(() => { - mock.restoreAll(); - }); - - it('basicModifyCreator', async () => { - assert.doesNotThrow(() => new ModifyCreator(mockAppBridge, mockAppId)); - - const mc = new ModifyCreator(mockAppBridge, mockAppId); - assert.ok(mc.startMessage() !== undefined); - assert.ok(mc.startMessage({ id: 'value' } as IMessage) !== undefined); - assert.ok(mc.startRoom() !== undefined); - assert.ok(mc.startRoom({ id: 'value' } as IRoom) !== undefined); - - assert.throws(() => mc.finish({} as any), { name: 'Error', message: 'Invalid builder passed to the ModifyCreator.finish function.' }); - }); - - it('msgModifyCreator', async () => { - const mc = new ModifyCreator(mockAppBridge, mockAppId); - - const msg = {} as IMessage; - const msgBd = mc.startMessage(msg); - await assert.rejects(() => mc.finish(msgBd), { name: 'Error', message: 'The "room" property is required.' }); - msgBd.setRoom(TestData.getRoom()); - assert.ok(msg.room !== undefined); - await assert.doesNotReject(() => mc.finish(msgBd)); - msgBd.setSender(TestData.getUser()); - assert.ok(msg.sender !== undefined); - - const msgBriSpy = mock.method(mockMessageBridge, 'doCreate'); - assert.strictEqual(await mc.finish(msgBd), 'msgId'); - assert.strictEqual(msgBriSpy.mock.calls.length, 1); - assert.deepStrictEqual(msgBriSpy.mock.calls[0].arguments, [msg, mockAppId]); - }); - - it('roomModifyCreator', async () => { - const mc = new ModifyCreator(mockAppBridge, mockAppId); - - const room = {} as IRoom; - const roomBd = mc.startRoom(room); - assert.throws(() => mc.finish(roomBd), { name: 'Error', message: 'Invalid type assigned to the room.' }); - roomBd.setType(RoomType.CHANNEL); - assert.strictEqual(room.type, RoomType.CHANNEL); - - assert.throws(() => mc.finish(roomBd), { name: 'Error', message: 'Invalid creator assigned to the room.' }); - roomBd.setCreator(TestData.getUser()); - assert.ok(room.creator !== undefined); - - assert.throws(() => mc.finish(roomBd), { name: 'Error', message: 'Invalid slugifiedName assigned to the room.' }); - roomBd.setSlugifiedName('testing-room'); - assert.strictEqual(room.slugifiedName, 'testing-room'); - - assert.throws(() => mc.finish(roomBd), { name: 'Error', message: 'Invalid displayName assigned to the room.' }); - roomBd.setDisplayName('Display Name'); - assert.strictEqual(room.displayName, 'Display Name'); - - const roomBriSpy = mock.method(mockRoomBridge, 'doCreate'); - assert.strictEqual(await mc.finish(roomBd), 'roomId'); - assert.strictEqual(roomBriSpy.mock.calls.length, 1); - assert.deepStrictEqual(roomBriSpy.mock.calls[0].arguments, [room, roomBd.getMembersToBeAddedUsernames(), mockAppId]); - }); -}); diff --git a/packages/apps/tests/server/accessors/ModifyExtender.test.ts b/packages/apps/tests/server/accessors/ModifyExtender.test.ts deleted file mode 100644 index f355661c42cd6..0000000000000 --- a/packages/apps/tests/server/accessors/ModifyExtender.test.ts +++ /dev/null @@ -1,77 +0,0 @@ -import * as assert from 'node:assert'; -import { afterEach, beforeEach, describe, it, mock } from 'node:test'; - -import type { IMessage } from '@rocket.chat/apps-engine/definition/messages'; -import type { IRoom } from '@rocket.chat/apps-engine/definition/rooms'; - -import { ModifyExtender } from '../../../src/server/accessors'; -import type { AppBridges, MessageBridge, RoomBridge } from '../../../src/server/bridges'; -import { TestData } from '../../test-data/utilities'; - -describe('ModifyExtender', () => { - let mockAppId: string; - let mockRoomBridge: RoomBridge; - let mockMessageBridge: MessageBridge; - let mockAppBridge: AppBridges; - - beforeEach(() => { - mockAppId = 'testing-app'; - - mockRoomBridge = { - doGetById(roomId: string, appId: string): Promise { - return Promise.resolve(TestData.getRoom()); - }, - doUpdate(room: IRoom, members: Array, appId: string): Promise { - return Promise.resolve(); - }, - } as RoomBridge; - - mockMessageBridge = { - doGetById(msgId: string, appId: string): Promise { - return Promise.resolve(TestData.getMessage()); - }, - doUpdate(msg: IMessage, appId: string): Promise { - return Promise.resolve(); - }, - } as MessageBridge; - - const rmBridge = mockRoomBridge; - const msgBridge = mockMessageBridge; - mockAppBridge = { - getMessageBridge() { - return msgBridge; - }, - getRoomBridge() { - return rmBridge; - }, - } as AppBridges; - }); - - afterEach(() => { - mock.restoreAll(); - }); - - it('useModifyExtender', async () => { - assert.doesNotThrow(() => new ModifyExtender(mockAppBridge, mockAppId)); - - const me = new ModifyExtender(mockAppBridge, mockAppId); - - const doGetByIdRoomSpy = mock.method(mockRoomBridge, 'doGetById'); - const doUpdateRoomSpy = mock.method(mockRoomBridge, 'doUpdate'); - const doGetByIdMsgSpy = mock.method(mockMessageBridge, 'doGetById'); - const doUpdateMsgSpy = mock.method(mockMessageBridge, 'doUpdate'); - - assert.ok((await me.extendRoom('roomId', TestData.getUser())) !== undefined); - assert.strictEqual(doGetByIdRoomSpy.mock.calls.length, 1); - assert.deepStrictEqual(doGetByIdRoomSpy.mock.calls[0].arguments, ['roomId', mockAppId]); - assert.ok((await me.extendMessage('msgId', TestData.getUser())) !== undefined); - assert.strictEqual(doGetByIdMsgSpy.mock.calls.length, 1); - assert.deepStrictEqual(doGetByIdMsgSpy.mock.calls[0].arguments, ['msgId', mockAppId]); - - assert.throws(() => me.finish({} as any), { name: 'Error', message: 'Invalid extender passed to the ModifyExtender.finish function.' }); - assert.strictEqual(await me.finish(await me.extendRoom('roomId', TestData.getUser())), undefined); - assert.ok(doUpdateRoomSpy.mock.calls.length > 0); - assert.strictEqual(await me.finish(await me.extendMessage('msgId', TestData.getUser())), undefined); - assert.ok(doUpdateMsgSpy.mock.calls.length > 0); - }); -}); diff --git a/packages/apps/tests/server/accessors/ModifyUpdater.test.ts b/packages/apps/tests/server/accessors/ModifyUpdater.test.ts deleted file mode 100644 index e3c31bb450ddf..0000000000000 --- a/packages/apps/tests/server/accessors/ModifyUpdater.test.ts +++ /dev/null @@ -1,140 +0,0 @@ -import * as assert from 'node:assert'; -import { afterEach, beforeEach, describe, it, mock } from 'node:test'; - -import type { ILivechatRoom } from '@rocket.chat/apps-engine/definition/livechat/ILivechatRoom'; -import type { IMessage } from '@rocket.chat/apps-engine/definition/messages'; -import type { IRoom } from '@rocket.chat/apps-engine/definition/rooms'; -import { RoomType } from '@rocket.chat/apps-engine/definition/rooms'; - -import { MessageBuilder, ModifyUpdater, RoomBuilder } from '../../../src/server/accessors'; -import type { AppBridges, MessageBridge, RoomBridge } from '../../../src/server/bridges'; -import { TestData } from '../../test-data/utilities'; - -describe('ModifyUpdater', () => { - let mockAppId: string; - let mockRoomBridge: RoomBridge; - let mockMessageBridge: MessageBridge; - let mockAppBridge: AppBridges; - - beforeEach(() => { - mockAppId = 'testing-app'; - - mockRoomBridge = { - doGetById(roomId: string, appId: string): Promise { - return Promise.resolve(TestData.getRoom()); - }, - doUpdate(room: IRoom, members: Array, appId: string): Promise { - return Promise.resolve(); - }, - } as RoomBridge; - - mockMessageBridge = { - doGetById(msgId: string, appId: string): Promise { - return Promise.resolve(TestData.getMessage()); - }, - doUpdate(msg: IMessage, appId: string): Promise { - return Promise.resolve(); - }, - } as MessageBridge; - - const rmBridge = mockRoomBridge; - const msgBridge = mockMessageBridge; - mockAppBridge = { - getMessageBridge() { - return msgBridge; - }, - getRoomBridge() { - return rmBridge; - }, - } as AppBridges; - }); - - afterEach(() => { - mock.restoreAll(); - }); - - it('basicModifyUpdater', async () => { - assert.doesNotThrow(() => new ModifyUpdater(mockAppBridge, mockAppId)); - - const mc = new ModifyUpdater(mockAppBridge, mockAppId); - assert.ok((await mc.message('msgId', TestData.getUser())) !== undefined); - assert.ok((await mc.room('roomId', TestData.getUser())) !== undefined); - - assert.throws(() => mc.finish({} as any), { - name: 'Error', - message: 'Invalid builder passed to the ModifyUpdater.finish function.', - }); - }); - - it('msgModifyUpdater', async () => { - const mc = new ModifyUpdater(mockAppBridge, mockAppId); - - const msg = {} as IMessage; - const msgBd = new MessageBuilder(msg); - assert.throws(() => mc.finish(msgBd), { name: 'Error', message: 'The "room" property is required.' }); - msgBd.setRoom(TestData.getRoom()); - assert.ok(msg.room !== undefined); - assert.throws(() => mc.finish(msgBd), { name: 'Error', message: "Invalid message, can't update a message without an id." }); - msg.id = 'testing-msg'; - assert.throws(() => mc.finish(msgBd), { name: 'Error', message: 'Invalid sender assigned to the message.' }); - msgBd.setSender(TestData.getUser()); - assert.ok(msg.sender !== undefined); - - const msgBriSpy = mock.method(mockMessageBridge, 'doUpdate'); - assert.strictEqual(await mc.finish(msgBd), undefined); - assert.strictEqual(msgBriSpy.mock.calls.length, 1); - assert.deepStrictEqual(msgBriSpy.mock.calls[0].arguments, [msg, mockAppId]); - }); - - it('roomModifyUpdater', async () => { - const mc = new ModifyUpdater(mockAppBridge, mockAppId); - - const room = {} as IRoom; - const roomBd = new RoomBuilder(room); - assert.throws(() => mc.finish(roomBd), { name: 'Error', message: 'Invalid room, can not update a room without an id.' }); - room.id = 'testing-room'; - - assert.throws(() => mc.finish(roomBd), { name: 'Error', message: 'Invalid type assigned to the room.' }); - roomBd.setType(RoomType.CHANNEL); - assert.strictEqual(room.type, RoomType.CHANNEL); - - assert.throws(() => mc.finish(roomBd), { name: 'Error', message: 'Invalid creator assigned to the room.' }); - roomBd.setCreator(TestData.getUser()); - assert.ok(room.creator !== undefined); - - assert.throws(() => mc.finish(roomBd), { name: 'Error', message: 'Invalid slugifiedName assigned to the room.' }); - roomBd.setSlugifiedName('testing-room'); - assert.strictEqual(room.slugifiedName, 'testing-room'); - - assert.throws(() => mc.finish(roomBd), { name: 'Error', message: 'Invalid displayName assigned to the room.' }); - roomBd.setDisplayName('Display Name'); - assert.strictEqual(room.displayName, 'Display Name'); - - const roomBriSpy = mock.method(mockRoomBridge, 'doUpdate'); - assert.strictEqual(await mc.finish(roomBd), undefined); - assert.strictEqual(roomBriSpy.mock.calls.length, 1); - assert.deepStrictEqual(roomBriSpy.mock.calls[0].arguments, [room, roomBd.getMembersToBeAddedUsernames(), mockAppId]); - }); - - it('livechatRoomModifyUpdater', async () => { - const mc = new ModifyUpdater(mockAppBridge, mockAppId); - - const room = {} as ILivechatRoom; - const roomBd = new RoomBuilder(room); - assert.throws(() => mc.finish(roomBd), { name: 'Error', message: 'Invalid room, can not update a room without an id.' }); - room.id = 'testing-room'; - - assert.throws(() => mc.finish(roomBd), { name: 'Error', message: 'Invalid type assigned to the room.' }); - roomBd.setType(RoomType.LIVE_CHAT); - assert.strictEqual(room.type, RoomType.LIVE_CHAT); - - assert.throws(() => mc.finish(roomBd), { name: 'Error', message: 'Invalid displayName assigned to the room.' }); - roomBd.setDisplayName('Display Name'); - assert.strictEqual(room.displayName, 'Display Name'); - - const roomBriSpy = mock.method(mockRoomBridge, 'doUpdate'); - assert.strictEqual(await mc.finish(roomBd), undefined); - assert.strictEqual(roomBriSpy.mock.calls.length, 1); - assert.deepStrictEqual(roomBriSpy.mock.calls[0].arguments, [room, roomBd.getMembersToBeAddedUsernames(), mockAppId]); - }); -}); diff --git a/packages/apps/tests/server/accessors/Notifier.test.ts b/packages/apps/tests/server/accessors/Notifier.test.ts deleted file mode 100644 index fd22099a3fdb4..0000000000000 --- a/packages/apps/tests/server/accessors/Notifier.test.ts +++ /dev/null @@ -1,50 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it, mock } from 'node:test'; - -import type { IMessage } from '@rocket.chat/apps-engine/definition/messages'; -import type { IRoom } from '@rocket.chat/apps-engine/definition/rooms'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import { MessageBuilder, Notifier } from '../../../src/server/accessors'; -import type { MessageBridge, UserBridge } from '../../../src/server/bridges'; -import { TestData } from '../../test-data/utilities'; - -describe('Notifier', () => { - it('useNotifier', async () => { - const mockUserBridge = {} as UserBridge; - const mockMsgBridge = { - doNotifyUser(user: IUser, msg: IMessage, appId: string): Promise { - return Promise.resolve(); - }, - doNotifyRoom(room: IRoom, msg: IMessage, appId: string): Promise { - return Promise.resolve(); - }, - } as MessageBridge; - - assert.doesNotThrow(() => new Notifier(mockUserBridge, mockMsgBridge, 'testing')); - - const noti = new Notifier(mockUserBridge, mockMsgBridge, 'testing'); - - const doNotifyRoomSpy = mock.method(mockMsgBridge, 'doNotifyRoom'); - const doNotifyUserSpy = mock.method(mockMsgBridge, 'doNotifyUser'); - - const room = TestData.getRoom(); - const user = TestData.getUser(); - const roomMsg = TestData.getMessage(); - const userMsg = TestData.getMessage(); - - await assert.doesNotReject(() => noti.notifyRoom(room, roomMsg)); - assert.strictEqual(doNotifyRoomSpy.mock.calls.length, 1); - assert.strictEqual(doNotifyRoomSpy.mock.calls[0].arguments[0], room); - assert.strictEqual(doNotifyRoomSpy.mock.calls[0].arguments[1], roomMsg); - assert.strictEqual(doNotifyRoomSpy.mock.calls[0].arguments[2], 'testing'); - - await assert.doesNotReject(() => noti.notifyUser(user, userMsg)); - assert.strictEqual(doNotifyUserSpy.mock.calls.length, 1); - assert.strictEqual(doNotifyUserSpy.mock.calls[0].arguments[0], user); - assert.strictEqual(doNotifyUserSpy.mock.calls[0].arguments[1], userMsg); - assert.strictEqual(doNotifyUserSpy.mock.calls[0].arguments[2], 'testing'); - - assert.ok(noti.getMessageBuilder() instanceof MessageBuilder); - }); -}); diff --git a/packages/apps/tests/server/accessors/Persistence.test.ts b/packages/apps/tests/server/accessors/Persistence.test.ts deleted file mode 100644 index f101139363b2c..0000000000000 --- a/packages/apps/tests/server/accessors/Persistence.test.ts +++ /dev/null @@ -1,83 +0,0 @@ -import * as assert from 'node:assert'; -import { afterEach, beforeEach, describe, it, mock } from 'node:test'; - -import { RocketChatAssociationModel, RocketChatAssociationRecord } from '@rocket.chat/apps-engine/definition/metadata'; - -import { Persistence } from '../../../src/server/accessors'; -import type { PersistenceBridge } from '../../../src/server/bridges'; - -describe('Persistence', () => { - let mockAppId: string; - let mockPersisBridge: PersistenceBridge; - let mockAssoc: RocketChatAssociationRecord; - let data: object; - - beforeEach(() => { - mockAppId = 'testing-app'; - data = { hello: 'world' }; - - const theData = data; - mockPersisBridge = { - doCreate(d: any, appId: string): Promise { - return Promise.resolve('id'); - }, - doCreateWithAssociations(d: any, assocs: Array, appId: string): Promise { - return Promise.resolve('id2'); - }, - doUpdate(id: string, d: object, upsert: boolean, appId: string): Promise { - return Promise.resolve('id3'); - }, - doRemove(id: string, appId: string): Promise { - return Promise.resolve(theData); - }, - doRemoveByAssociations(assocs: Array, appId: string): Promise> { - return Promise.resolve([theData]); - }, - doUpdateByAssociations(associations: Array, d: object, upsert: boolean, appId: string): Promise { - return Promise.resolve('id4'); - }, - } as PersistenceBridge; - mockAssoc = new RocketChatAssociationRecord(RocketChatAssociationModel.USER, 'fake-id'); - }); - - afterEach(() => { - mock.restoreAll(); - }); - - it('usePersistenceAccessor', async () => { - assert.doesNotThrow(() => new Persistence(mockPersisBridge, mockAppId)); - - const sp1 = mock.method(mockPersisBridge, 'doCreate'); - const sp2 = mock.method(mockPersisBridge, 'doCreateWithAssociations'); - const sp3 = mock.method(mockPersisBridge, 'doUpdate'); - const sp4 = mock.method(mockPersisBridge, 'doRemove'); - const sp5 = mock.method(mockPersisBridge, 'doRemoveByAssociations'); - const sp6 = mock.method(mockPersisBridge, 'doUpdateByAssociations'); - - const ps = new Persistence(mockPersisBridge, mockAppId); - - assert.strictEqual(await ps.create(data), 'id'); - assert.strictEqual(sp1.mock.calls.length, 1); - assert.deepStrictEqual(sp1.mock.calls[0].arguments, [data, mockAppId]); - - assert.strictEqual(await ps.createWithAssociation(data, mockAssoc), 'id2'); - assert.strictEqual(await ps.createWithAssociations(data, [mockAssoc]), 'id2'); - assert.strictEqual(sp2.mock.calls.length, 2); - - assert.strictEqual(await ps.update('id', data), 'id3'); - assert.strictEqual(sp3.mock.calls.length, 1); - assert.deepStrictEqual(sp3.mock.calls[0].arguments, ['id', data, false, mockAppId]); - - assert.deepStrictEqual(await ps.remove('id'), data); - assert.strictEqual(sp4.mock.calls.length, 1); - assert.deepStrictEqual(sp4.mock.calls[0].arguments, ['id', mockAppId]); - - assert.ok((await ps.removeByAssociation(mockAssoc)) !== undefined); - assert.ok((await ps.removeByAssociations([mockAssoc])) !== undefined); - assert.strictEqual(sp5.mock.calls.length, 2); - - assert.ok((await ps.updateByAssociation(mockAssoc, data)) !== undefined); - assert.ok((await ps.updateByAssociations([mockAssoc], data)) !== undefined); - assert.strictEqual(sp6.mock.calls.length, 2); - }); -}); diff --git a/packages/apps/tests/server/accessors/PersistenceRead.test.ts b/packages/apps/tests/server/accessors/PersistenceRead.test.ts deleted file mode 100644 index 865b19abdfa17..0000000000000 --- a/packages/apps/tests/server/accessors/PersistenceRead.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { RocketChatAssociationRecord } from '@rocket.chat/apps-engine/definition/metadata'; - -import { PersistenceRead } from '../../../src/server/accessors'; -import type { PersistenceBridge } from '../../../src/server/bridges'; - -describe('PersistenceRead', () => { - it('usePersistenceRead', async () => { - const mockPersisBridge = { - doReadById(id: string, appId: string): Promise { - return Promise.resolve({ id, appId }); - }, - doReadByAssociations(assocs: Array, appId: string): Promise> { - return Promise.resolve([{ appId }]); - }, - } as PersistenceBridge; - - assert.doesNotThrow(() => new PersistenceRead(mockPersisBridge, 'testing')); - - const pr = new PersistenceRead(mockPersisBridge, 'testing'); - assert.deepStrictEqual(await pr.read('thing'), { id: 'thing', appId: 'testing' }); - assert.deepStrictEqual(await pr.readByAssociation({} as RocketChatAssociationRecord), [{ appId: 'testing' }]); - assert.deepStrictEqual(await pr.readByAssociations([{} as RocketChatAssociationRecord]), [{ appId: 'testing' }]); - }); -}); diff --git a/packages/apps/tests/server/accessors/Reader.test.ts b/packages/apps/tests/server/accessors/Reader.test.ts deleted file mode 100644 index cbfdf00256fab..0000000000000 --- a/packages/apps/tests/server/accessors/Reader.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { - ICloudWorkspaceRead, - IEnvironmentRead, - IExperimentalRead, - ILivechatRead, - IMessageRead, - INotifier, - IPersistenceRead, - IRoleRead, - IRoomRead, - IUploadRead, - IUserRead, - IVideoConferenceRead, -} from '@rocket.chat/apps-engine/definition/accessors'; -import type { IContactRead } from '@rocket.chat/apps-engine/definition/accessors/IContactRead'; -import type { IOAuthAppsReader } from '@rocket.chat/apps-engine/definition/accessors/IOAuthAppsReader'; -import type { IThreadRead } from '@rocket.chat/apps-engine/definition/accessors/IThreadRead'; - -import { Reader } from '../../../src/server/accessors'; - -describe('Reader', () => { - const env = {} as IEnvironmentRead; - const msg = {} as IMessageRead; - const pr = {} as IPersistenceRead; - const rm = {} as IRoomRead; - const ur = {} as IUserRead; - const ni = {} as INotifier; - const livechat = {} as ILivechatRead; - const upload = {} as IUploadRead; - const cloud = {} as ICloudWorkspaceRead; - const videoConf = {} as IVideoConferenceRead; - const oauthApps = {} as IOAuthAppsReader; - const thread = {} as IThreadRead; - const role = {} as IRoleRead; - const contact = {} as IContactRead; - const experimental = {} as IExperimentalRead; - - it('useReader', () => { - assert.doesNotThrow( - () => new Reader(env, msg, pr, rm, ur, ni, livechat, upload, cloud, videoConf, contact, oauthApps, thread, role, experimental), - ); - - const rd = new Reader(env, msg, pr, rm, ur, ni, livechat, upload, cloud, videoConf, contact, oauthApps, thread, role, experimental); - - assert.ok(rd.getEnvironmentReader() !== undefined); - assert.ok(rd.getMessageReader() !== undefined); - assert.ok(rd.getNotifier() !== undefined); - assert.ok(rd.getPersistenceReader() !== undefined); - assert.ok(rd.getRoomReader() !== undefined); - assert.ok(rd.getUserReader() !== undefined); - assert.ok(rd.getLivechatReader() !== undefined); - assert.ok(rd.getUploadReader() !== undefined); - assert.ok(rd.getVideoConferenceReader() !== undefined); - assert.ok(rd.getRoleReader() !== undefined); - }); -}); diff --git a/packages/apps/tests/server/accessors/RoomBuilder.test.ts b/packages/apps/tests/server/accessors/RoomBuilder.test.ts deleted file mode 100644 index 403dd97a86e85..0000000000000 --- a/packages/apps/tests/server/accessors/RoomBuilder.test.ts +++ /dev/null @@ -1,92 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { IRoom } from '@rocket.chat/apps-engine/definition/rooms'; -import { RoomType } from '@rocket.chat/apps-engine/definition/rooms'; - -import { RoomBuilder } from '../../../src/server/accessors'; -import { TestData } from '../../test-data/utilities'; - -describe('RoomBuilder', () => { - it('basicRoomBuilder', () => { - assert.doesNotThrow(() => new RoomBuilder()); - assert.doesNotThrow(() => new RoomBuilder(TestData.getRoom())); - }); - - it('settingOnRoomBuilder', () => { - const rbOnce = new RoomBuilder(); - - // setData just replaces the passed in object, so let's treat it differently - assert.strictEqual(rbOnce.setData({ displayName: 'Testing Channel' } as IRoom), rbOnce); - assert.strictEqual((rbOnce as any).room.displayName, 'Testing Channel'); - - const room: IRoom = {} as IRoom; - const rb = new RoomBuilder(room); - assert.strictEqual(rb.setDisplayName('Just a Test'), rb); - assert.deepStrictEqual(room.displayName, 'Just a Test'); - assert.deepStrictEqual(rb.getDisplayName(), 'Just a Test'); - - assert.strictEqual(rb.setSlugifiedName('just_a_test'), rb); - assert.deepStrictEqual(room.slugifiedName, 'just_a_test'); - assert.deepStrictEqual(rb.getSlugifiedName(), 'just_a_test'); - - assert.strictEqual(rb.setType(RoomType.CHANNEL), rb); - assert.deepStrictEqual(room.type, RoomType.CHANNEL); - assert.deepStrictEqual(rb.getType(), RoomType.CHANNEL); - - const creator = TestData.getUser(); - - assert.strictEqual(rb.setCreator(creator), rb); - assert.deepStrictEqual(room.creator, creator); - assert.deepStrictEqual(rb.getCreator(), creator); - - assert.strictEqual(rb.addUsername('testing.username'), rb); - assert.strictEqual(room.usernames, undefined); - assert.ok(rb.getUsernames().length > 0); - assert.strictEqual(room.usernames, undefined); - assert.deepStrictEqual(rb.getUsernames()[0], 'testing.username'); - assert.strictEqual(rb.addUsername('another.username'), rb); - assert.strictEqual(room.usernames, undefined); - assert.strictEqual(rb.getUsernames().length, 2); - - assert.strictEqual(rb.setUsernames([]), rb); - assert.strictEqual(room.usernames, undefined); - assert.strictEqual(rb.getUsernames().length, 0); - - assert.strictEqual(rb.addMemberToBeAddedByUsername('testing.username'), rb); - assert.ok(rb.getMembersToBeAddedUsernames().length > 0); - assert.deepStrictEqual(rb.getMembersToBeAddedUsernames()[0], 'testing.username'); - assert.strictEqual(rb.addMemberToBeAddedByUsername('another.username'), rb); - assert.strictEqual(rb.getMembersToBeAddedUsernames().length, 2); - - assert.strictEqual(rb.setMembersToBeAddedByUsernames([]), rb); - assert.strictEqual(rb.getMembersToBeAddedUsernames().length, 0); - - assert.strictEqual(rb.setDefault(true), rb); - assert.ok(room.isDefault); - assert.ok(rb.getIsDefault()); - - assert.strictEqual(rb.setReadOnly(false), rb); - assert.ok(!room.isReadOnly); - assert.ok(!rb.getIsReadOnly()); - - assert.strictEqual(rb.setDisplayingOfSystemMessages(true), rb); - assert.ok(room.displaySystemMessages); - assert.ok(rb.getDisplayingOfSystemMessages()); - - assert.strictEqual(rb.addCustomField('thing', {}), rb); - assert.ok(Object.keys(room.customFields).length > 0); - assert.ok(Object.keys(rb.getCustomFields()).length > 0); - assert.ok(room.customFields.thing !== undefined); - assert.ok(rb.getCustomFields().thing !== undefined); - assert.strictEqual(rb.addCustomField('another', { thingy: 'two' }), rb); - assert.deepStrictEqual(room.customFields.another, { thingy: 'two' }); - assert.deepStrictEqual(rb.getCustomFields().another, { thingy: 'two' }); - - assert.strictEqual(rb.setCustomFields({}), rb); - assert.strictEqual(Object.keys(room.customFields).length, 0); - assert.strictEqual(Object.keys(rb.getCustomFields()).length, 0); - - assert.strictEqual(rb.getRoom(), room); - }); -}); diff --git a/packages/apps/tests/server/accessors/RoomExtender.test.ts b/packages/apps/tests/server/accessors/RoomExtender.test.ts deleted file mode 100644 index 099f7598a1b2f..0000000000000 --- a/packages/apps/tests/server/accessors/RoomExtender.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { IRoom } from '@rocket.chat/apps-engine/definition/rooms'; - -import { RoomExtender } from '../../../src/server/accessors'; -import { TestData } from '../../test-data/utilities'; - -describe('RoomExtender', () => { - it('basicRoomExtender', () => { - assert.doesNotThrow(() => new RoomExtender({} as IRoom)); - assert.doesNotThrow(() => new RoomExtender(TestData.getRoom())); - }); - - it('usingRoomExtender', () => { - const room: IRoom = {} as IRoom; - const re = new RoomExtender(room); - - assert.ok(room.customFields === undefined); - assert.strictEqual(re.addCustomField('thing', 'value'), re); - assert.ok(room.customFields !== undefined); - assert.strictEqual(room.customFields.thing as any, 'value'); - assert.throws(() => re.addCustomField('thing', 'second'), { - name: 'Error', - message: 'The room already contains a custom field by the key: thing', - }); - assert.throws(() => re.addCustomField('thing.', 'second'), { - name: 'Error', - message: 'The given key contains a period, which is not allowed. Key: thing.', - }); - - assert.ok(room.usernames === undefined); - assert.strictEqual(re.addMember(TestData.getUser('theId', 'bradley')), re); - assert.ok(room.usernames === undefined); - assert.ok(re.getMembersBeingAdded() !== undefined); - assert.ok(re.getMembersBeingAdded().length > 0); - assert.ok(re.getMembersBeingAdded()[0] !== undefined); - assert.strictEqual(re.getMembersBeingAdded()[0].username, 'bradley'); - assert.throws(() => re.addMember(TestData.getUser('theSameUsername', 'bradley')), { - name: 'Error', - message: 'The user is already in the room.', - }); - - assert.notStrictEqual(re.getRoom(), room); - assert.deepStrictEqual(re.getRoom(), room); - }); -}); diff --git a/packages/apps/tests/server/accessors/RoomRead.test.ts b/packages/apps/tests/server/accessors/RoomRead.test.ts deleted file mode 100644 index aa4b9b7b2b3f9..0000000000000 --- a/packages/apps/tests/server/accessors/RoomRead.test.ts +++ /dev/null @@ -1,150 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { IMessageRaw } from '@rocket.chat/apps-engine/definition/messages'; -import type { IRoom, IRoomRaw } from '@rocket.chat/apps-engine/definition/rooms'; -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import { RoomRead } from '../../../src/server/accessors'; -import type { RoomBridge } from '../../../src/server/bridges'; -import { TestData } from '../../test-data/utilities'; - -describe('RoomRead', () => { - const room = TestData.getRoom(); - room.id = room.id || 'room-id'; - const user = TestData.getUser(); - const messages: IMessageRaw[] = ['507f1f77bcf86cd799439011', '507f191e810c19729de860ea'].map((id) => TestData.getMessageRaw(id)); - const unreadRoomId = messages[0].roomId; - const unreadUserId = messages[0].sender._id; - - const theRooms: IRoomRaw[] = [ - { - id: room.id, - slugifiedName: room.slugifiedName, - displayName: room.displayName, - type: room.type, - creator: { - _id: room.creator.id, - username: room.creator.username, - name: room.creator.name, - }, - }, - ]; - - const mockRoomBridgeWithRoom = { - doGetById(id: string, appId: string): Promise { - return Promise.resolve(room); - }, - doGetByName(name: string, appId: string): Promise { - return Promise.resolve(room); - }, - doGetCreatorById(id: string, appId: string): Promise { - return Promise.resolve(user); - }, - doGetCreatorByName(name: string, appId: string): Promise { - return Promise.resolve(user); - }, - doGetDirectByUsernames(usernames: Array, appId: string): Promise { - return Promise.resolve(room); - }, - doGetMembers(name: string, appId: string): Promise> { - return Promise.resolve([user]); - }, - doGetAllRooms(filter: any, appId: string): Promise> { - return Promise.resolve(theRooms); - }, - doGetMessages(roomId: string, options: any, appId: string): Promise { - return Promise.resolve(messages); - }, - doGetUnreadByUser(roomId: string, uid: string, options: any, appId: string): Promise { - if (roomId === unreadRoomId && uid === unreadUserId) { - return Promise.resolve(messages); - } - return Promise.resolve([]); - }, - } as unknown as RoomBridge; - - it('expectDataFromRoomRead', async () => { - assert.doesNotThrow(() => new RoomRead(mockRoomBridgeWithRoom, 'testing-app')); - - const rr = new RoomRead(mockRoomBridgeWithRoom, 'testing-app'); - - assert.ok((await rr.getById('fake')) !== undefined); - assert.strictEqual(await rr.getById('fake'), room); - assert.ok((await rr.getByName('testing-room')) !== undefined); - assert.strictEqual(await rr.getByName('testing-room'), room); - assert.ok((await rr.getCreatorUserById('testing')) !== undefined); - assert.strictEqual(await rr.getCreatorUserById('testing'), user); - assert.ok((await rr.getCreatorUserByName('testing')) !== undefined); - assert.strictEqual(await rr.getCreatorUserByName('testing'), user); - assert.ok((await rr.getDirectByUsernames([user.username])) !== undefined); - assert.strictEqual(await rr.getDirectByUsernames([user.username]), room); - assert.ok((await rr.getMessages('testing')) !== undefined); - assert.strictEqual(await rr.getMessages('testing'), messages); - assert.ok((await rr.getAllRooms()) !== undefined); - assert.deepStrictEqual(await rr.getAllRooms(), [ - { - id: room.id, - slugifiedName: room.slugifiedName, - displayName: room.displayName, - type: room.type, - creator: { - _id: room.creator.id, - username: room.creator.username, - name: room.creator.name, - }, - }, - ]); - assert.ok((await rr.getUnreadByUser(unreadRoomId, unreadUserId)) !== undefined); - assert.deepStrictEqual(await rr.getUnreadByUser(unreadRoomId, unreadUserId), messages); - - assert.ok((await rr.getUnreadByUser('fake', 'fake')) !== undefined); - assert.deepStrictEqual(await rr.getUnreadByUser('fake', 'fake'), []); - }); - - it('useTheIterators', async () => { - assert.doesNotThrow(() => new RoomRead(mockRoomBridgeWithRoom, 'testing-app')); - - const rr = new RoomRead(mockRoomBridgeWithRoom, 'testing-app'); - - assert.ok((await rr.getMembers('testing')) !== undefined); - assert.ok(((await rr.getMembers('testing')) as Array).length > 0); - assert.strictEqual((await rr.getMembers('testing'))[0], user); - }); - - it('validateGetAllRoomsEdgeCases', async () => { - const rr = new RoomRead(mockRoomBridgeWithRoom, 'testing-app'); - - // Test negative limit - await assert.rejects(async () => rr.getAllRooms({}, { limit: -1 })); - await assert.rejects(async () => rr.getAllRooms({}, { limit: -100 })); - - // Test zero limit - await assert.rejects(async () => rr.getAllRooms({}, { limit: 0 })); - // Test non-finite limit values - await assert.rejects(async () => rr.getAllRooms({}, { limit: NaN })); - await assert.rejects(async () => rr.getAllRooms({}, { limit: Infinity })); - await assert.rejects(async () => rr.getAllRooms({}, { limit: -Infinity })); - - // Test limit > 100 (existing test case) - await assert.rejects(async () => rr.getAllRooms({}, { limit: 101 })); - await assert.rejects(async () => rr.getAllRooms({}, { limit: 200 })); - - // Test negative skip values - await assert.rejects(async () => rr.getAllRooms({}, { skip: -1 })); - await assert.rejects(async () => rr.getAllRooms({}, { skip: -100 })); - - // Test non-finite skip values - await assert.rejects(async () => rr.getAllRooms({}, { skip: NaN })); - await assert.rejects(async () => rr.getAllRooms({}, { skip: Infinity })); - await assert.rejects(async () => rr.getAllRooms({}, { skip: -Infinity })); - - // Test valid calls to ensure validation doesn't break normal behavior - await assert.doesNotReject(async () => rr.getAllRooms({}, { limit: 1 })); - await assert.doesNotReject(async () => rr.getAllRooms({}, { limit: 50 })); - await assert.doesNotReject(async () => rr.getAllRooms({}, { limit: 100 })); - await assert.doesNotReject(async () => rr.getAllRooms({}, { skip: 0 })); - await assert.doesNotReject(async () => rr.getAllRooms({}, { skip: 10 })); - await assert.doesNotReject(async () => rr.getAllRooms({}, { limit: 50, skip: 10 })); - }); -}); diff --git a/packages/apps/tests/server/accessors/ServerSettingRead.test.ts b/packages/apps/tests/server/accessors/ServerSettingRead.test.ts deleted file mode 100644 index e35e089803943..0000000000000 --- a/packages/apps/tests/server/accessors/ServerSettingRead.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import { ServerSettingRead } from '../../../src/server/accessors'; -import type { ServerSettingBridge } from '../../../src/server/bridges'; -import { TestData } from '../../test-data/utilities'; - -describe('ServerSettingRead', () => { - it('expectDataFromServerSettingRead', async () => { - const setting = TestData.getSetting('testing'); - - const theSetting = setting; - const mockServerSettingBridge = { - doGetOneById(id: string, appId: string) { - return Promise.resolve(id === 'testing' ? theSetting : undefined); - }, - doIsReadableById(id: string, appId: string): Promise { - return Promise.resolve(true); - }, - } as ServerSettingBridge; - - assert.doesNotThrow(() => new ServerSettingRead(mockServerSettingBridge, 'testing-app')); - - const ssr = new ServerSettingRead(mockServerSettingBridge, 'testing-app'); - - assert.ok((await ssr.getOneById('testing')) !== undefined); - assert.deepStrictEqual(await ssr.getOneById('testing'), setting); - assert.deepStrictEqual(await ssr.getValueById('testing'), setting.packageValue); - setting.value = 'theValue'; - assert.strictEqual(await ssr.getValueById('testing'), 'theValue'); - await assert.rejects(async () => ssr.getValueById('fake'), { - name: 'Error', - message: 'No Server Setting found, or it is unaccessible, by the id of "fake".', - }); - assert.throws(() => ssr.getAll(), { - name: 'Error', - message: 'Method not implemented.', - }); - assert.strictEqual(await ssr.isReadableById('testing'), true); - }); -}); diff --git a/packages/apps/tests/server/accessors/ServerSettingsModify.test.ts b/packages/apps/tests/server/accessors/ServerSettingsModify.test.ts deleted file mode 100644 index 736751265acfc..0000000000000 --- a/packages/apps/tests/server/accessors/ServerSettingsModify.test.ts +++ /dev/null @@ -1,54 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it, mock } from 'node:test'; - -import type { ISetting } from '@rocket.chat/apps-engine/definition/settings'; - -import { ServerSettingsModify } from '../../../src/server/accessors'; -import type { ServerSettingBridge } from '../../../src/server/bridges'; -import { TestData } from '../../test-data/utilities'; - -describe('ServerSettingsModify', () => { - it('useServerSettingsModify', async () => { - const setting = TestData.getSetting(); - const mockAppId = 'testing-app'; - const mockServerSettingBridge = { - doHideGroup(name: string, appId: string): Promise { - return Promise.resolve(); - }, - doHideSetting(id: string, appId: string): Promise { - return Promise.resolve(); - }, - doUpdateOne(setting: ISetting, appId: string): Promise { - return Promise.resolve(); - }, - doIncrementValue(id: ISetting['id'], value: number, appId: string): Promise { - return Promise.resolve(); - }, - } as ServerSettingBridge; - - assert.doesNotThrow(() => new ServerSettingsModify(mockServerSettingBridge, mockAppId)); - - const hideGroupSpy = mock.method(mockServerSettingBridge, 'doHideGroup'); - const hideSettingSpy = mock.method(mockServerSettingBridge, 'doHideSetting'); - const updateOneSpy = mock.method(mockServerSettingBridge, 'doUpdateOne'); - const incrementValueSpy = mock.method(mockServerSettingBridge, 'doIncrementValue'); - - const ssm = new ServerSettingsModify(mockServerSettingBridge, mockAppId); - - assert.ok((await ssm.hideGroup('api')) === undefined); - assert.strictEqual(hideGroupSpy.mock.calls.length, 1); - assert.deepStrictEqual(hideGroupSpy.mock.calls[0].arguments, ['api', mockAppId]); - - assert.ok((await ssm.hideSetting('api')) === undefined); - assert.strictEqual(hideSettingSpy.mock.calls.length, 1); - assert.deepStrictEqual(hideSettingSpy.mock.calls[0].arguments, ['api', mockAppId]); - - assert.ok((await ssm.modifySetting(setting)) === undefined); - assert.strictEqual(updateOneSpy.mock.calls.length, 1); - assert.deepStrictEqual(updateOneSpy.mock.calls[0].arguments, [setting, mockAppId]); - - assert.ok((await ssm.incrementValue(setting.id, 5)) === undefined); - assert.strictEqual(incrementValueSpy.mock.calls.length, 1); - assert.deepStrictEqual(incrementValueSpy.mock.calls[0].arguments, [setting.id, 5, mockAppId]); - }); -}); diff --git a/packages/apps/tests/server/accessors/SettingRead.test.ts b/packages/apps/tests/server/accessors/SettingRead.test.ts deleted file mode 100644 index 4d222cd8a3533..0000000000000 --- a/packages/apps/tests/server/accessors/SettingRead.test.ts +++ /dev/null @@ -1,36 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { ProxiedApp } from '../../../src/server/ProxiedApp'; -import { SettingRead } from '../../../src/server/accessors'; -import type { IAppStorageItem } from '../../../src/server/storage'; -import { TestData } from '../../test-data/utilities'; - -describe('SettingRead', () => { - it('appSettingRead', async () => { - const mockStorageItem = { - settings: {}, - } as IAppStorageItem; - mockStorageItem.settings.testing = TestData.getSetting('testing'); - - const si = mockStorageItem; - const mockProxiedApp = { - getStorageItem(): IAppStorageItem { - return si; - }, - } as ProxiedApp; - - assert.doesNotThrow(() => new SettingRead({} as ProxiedApp)); - - const sr = new SettingRead(mockProxiedApp); - assert.ok((await sr.getById('testing')) !== undefined); - assert.deepStrictEqual(await sr.getById('testing'), TestData.getSetting('testing')); - assert.strictEqual(await sr.getValueById('testing'), 'The packageValue'); - mockStorageItem.settings.testing.value = 'my value'; - assert.strictEqual(await sr.getValueById('testing'), 'my value'); - await assert.rejects(() => sr.getValueById('superfake'), { - name: 'Error', - message: 'Setting "superfake" does not exist.', - }); - }); -}); diff --git a/packages/apps/tests/server/accessors/SettingUpdater.test.ts b/packages/apps/tests/server/accessors/SettingUpdater.test.ts deleted file mode 100644 index 136e8b1c15c0d..0000000000000 --- a/packages/apps/tests/server/accessors/SettingUpdater.test.ts +++ /dev/null @@ -1,104 +0,0 @@ -import * as assert from 'node:assert'; -import { afterEach, beforeEach, describe, it, mock } from 'node:test'; - -import type { ProxiedApp } from '../../../src/server/ProxiedApp'; -import { SettingUpdater } from '../../../src/server/accessors'; -import type { AppSettingsManager } from '../../../src/server/managers'; -import type { IAppStorageItem } from '../../../src/server/storage'; -import { TestData } from '../../test-data/utilities'; - -describe('SettingUpdater', () => { - let mockStorageItem: IAppStorageItem; - let mockProxiedApp: ProxiedApp; - let mockSettingsManager: AppSettingsManager; - - beforeEach(() => { - // Set up mock storage with test settings - mockStorageItem = { - settings: {}, - } as IAppStorageItem; - - mockStorageItem.settings.singleValue = TestData.getSetting('singleValue'); - mockStorageItem.settings.multiValue = { - ...TestData.getSetting('multiValue'), - values: [ - { key: 'key1', i18nLabel: 'value1' }, - { key: 'key2', i18nLabel: 'value2' }, - ], - }; - - // Mock ProxiedApp - const si = mockStorageItem; - mockProxiedApp = { - getStorageItem(): IAppStorageItem { - return si; - }, - getID(): string { - return 'test-app-id'; - }, - } as ProxiedApp; - - // Mock AppSettingsManager - mockSettingsManager = {} as AppSettingsManager; - mockSettingsManager.getAppSetting = (appId: string, settingId: string) => { - return mockStorageItem.settings[settingId]; - }; - mockSettingsManager.updateAppSetting = (appId: string, setting: any) => { - mockStorageItem.settings[setting.id] = setting; - return Promise.resolve(); - }; - }); - - afterEach(() => { - mock.restoreAll(); - }); - - it('updateValueSuccessfully', async () => { - const updateAppSettingSpy = mock.method(mockSettingsManager, 'updateAppSetting'); - const settingUpdater = new SettingUpdater(mockProxiedApp, mockSettingsManager); - - await settingUpdater.updateValue('singleValue', 'updated value'); - - assert.ok(updateAppSettingSpy.mock.calls.length > 0); - assert.strictEqual(mockStorageItem.settings.singleValue.value, 'updated value'); - // Verify updatedAt was set - assert.ok(mockStorageItem.settings.singleValue.updatedAt !== undefined); - }); - - it('updateValueThrowsErrorForNonExistentSetting', async () => { - const settingUpdater = new SettingUpdater(mockProxiedApp, mockSettingsManager); - - await assert.rejects(() => settingUpdater.updateValue('nonExistent', 'value'), { - name: 'Error', - message: 'Setting "nonExistent" not found for app test-app-id', - }); - }); - - it('updateSelectOptionsSuccessfully', async () => { - const updateAppSettingSpy = mock.method(mockSettingsManager, 'updateAppSetting'); - const settingUpdater = new SettingUpdater(mockProxiedApp, mockSettingsManager); - const newValues = [ - { key: 'key3', i18nLabel: 'value3' }, - { key: 'key4', i18nLabel: 'value4' }, - ]; - - await settingUpdater.updateSelectOptions('multiValue', newValues); - - assert.ok(updateAppSettingSpy.mock.calls.length > 0); - const updatedValues = mockStorageItem.settings.multiValue.values; - // Should completely replace old values - assert.strictEqual((updatedValues ?? []).length, 2); - assert.deepStrictEqual(updatedValues, newValues); - // Verify updatedAt was set - assert.ok(mockStorageItem.settings.multiValue.updatedAt !== undefined); - }); - - it('updateSelectOptionsThrowsErrorForNonExistentSetting', async () => { - const settingUpdater = new SettingUpdater(mockProxiedApp, mockSettingsManager); - - await assert.rejects(() => settingUpdater.updateSelectOptions('nonExistent', [{ key: 'test', i18nLabel: 'value' }]), { - name: 'Error', - message: 'Setting "nonExistent" not found for app test-app-id', - }); - }); -}); diff --git a/packages/apps/tests/server/accessors/SettingsExtend.test.ts b/packages/apps/tests/server/accessors/SettingsExtend.test.ts deleted file mode 100644 index 944ad5ed8cfc0..0000000000000 --- a/packages/apps/tests/server/accessors/SettingsExtend.test.ts +++ /dev/null @@ -1,54 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { ISetting } from '@rocket.chat/apps-engine/definition/settings'; -import { SettingType } from '@rocket.chat/apps-engine/definition/settings'; - -import type { ProxiedApp } from '../../../src/server/ProxiedApp'; -import { SettingsExtend } from '../../../src/server/accessors'; -import type { IAppStorageItem } from '../../../src/server/storage'; - -describe('SettingsExtend', () => { - it('basicSettingsExtend', () => { - assert.doesNotThrow(() => new SettingsExtend({} as ProxiedApp)); - }); - - it('provideSettingToSettingsExtend', async () => { - const mockedStorageItem: IAppStorageItem = { - settings: {}, - } as IAppStorageItem; - - const mockedApp: ProxiedApp = { - getStorageItem: function _getStorageItem() { - return mockedStorageItem; - }, - } as ProxiedApp; - const se = new SettingsExtend(mockedApp); - - const setting: ISetting = { - id: 'testing', - type: SettingType.STRING, - packageValue: 'thing', - required: false, - public: false, - i18nLabel: 'Testing_Settings', - }; - - await assert.doesNotReject(() => se.provideSetting(setting)); - assert.ok(Object.keys(mockedStorageItem.settings).length > 0); - - const settingModified: ISetting = { - id: 'testing', - type: SettingType.STRING, - packageValue: 'thing', - required: false, - public: false, - i18nLabel: 'Testing_Thing', - value: 'dont-use-me', - }; - await assert.doesNotReject(() => se.provideSetting(settingModified)); - assert.ok(mockedStorageItem.settings.testing !== undefined); - assert.ok(mockedStorageItem.settings.testing.value === undefined); - assert.strictEqual(mockedStorageItem.settings.testing.i18nLabel, 'Testing_Thing'); - }); -}); diff --git a/packages/apps/tests/server/accessors/SlashCommandsExtend.test.ts b/packages/apps/tests/server/accessors/SlashCommandsExtend.test.ts deleted file mode 100644 index fec22df9093c9..0000000000000 --- a/packages/apps/tests/server/accessors/SlashCommandsExtend.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { ISlashCommand } from '@rocket.chat/apps-engine/definition/slashcommands'; - -import { SlashCommandsExtend } from '../../../src/server/accessors'; -import { CommandAlreadyExistsError } from '../../../src/server/errors'; -import type { AppSlashCommandManager } from '../../../src/server/managers'; - -describe('SlashCommandsExtend', () => { - it('basicSlashCommandsExtend', () => { - assert.doesNotThrow(() => new SlashCommandsExtend({} as AppSlashCommandManager, 'testing')); - }); - - it('provideCommandToCommandsExtend', async () => { - const commands = new Map>(); - const mockManager: AppSlashCommandManager = { - addCommand(appId: string, command: ISlashCommand) { - if (commands.has(appId)) { - const cmds = commands.get(appId); - if (cmds.find((v) => v.command === command.command)) { - throw new CommandAlreadyExistsError(command.command); - } - - cmds.push(command); - return; - } - - commands.set(appId, Array.from([command])); - }, - } as AppSlashCommandManager; - - const se = new SlashCommandsExtend(mockManager, 'testing'); - - const mockCommand: ISlashCommand = { - command: 'mock', - i18nDescription: 'Thing', - } as ISlashCommand; - - await assert.doesNotReject(() => se.provideSlashCommand(mockCommand)); - assert.strictEqual(commands.size, 1); - await assert.rejects(() => se.provideSlashCommand(mockCommand), { - name: 'CommandAlreadyExists', - message: 'The command "mock" already exists in the system.', - }); - }); -}); diff --git a/packages/apps/tests/server/accessors/SlashCommandsModify.test.ts b/packages/apps/tests/server/accessors/SlashCommandsModify.test.ts deleted file mode 100644 index 7202f688a3cdf..0000000000000 --- a/packages/apps/tests/server/accessors/SlashCommandsModify.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it, mock } from 'node:test'; - -import type { ISlashCommand } from '@rocket.chat/apps-engine/definition/slashcommands'; - -import { SlashCommandsModify } from '../../../src/server/accessors'; -import type { AppSlashCommandManager } from '../../../src/server/managers'; -import { TestData } from '../../test-data/utilities'; - -describe('SlashCommandsModify', () => { - it('useSlashCommandsModify', async () => { - const cmd = TestData.getSlashCommand(); - const mockAppId = 'testing-app'; - const mockCmdManager = { - modifyCommand(appId: string, command: ISlashCommand): void {}, - disableCommand(appId: string, command: string): void {}, - enableCommand(appId: string, command: string): void {}, - } as AppSlashCommandManager; - - assert.doesNotThrow(() => new SlashCommandsModify(mockCmdManager, mockAppId)); - - const modifySpy = mock.method(mockCmdManager, 'modifyCommand'); - const disableSpy = mock.method(mockCmdManager, 'disableCommand'); - const enableSpy = mock.method(mockCmdManager, 'enableCommand'); - - const scm = new SlashCommandsModify(mockCmdManager, mockAppId); - - assert.ok((await scm.modifySlashCommand(cmd)) === undefined); - assert.strictEqual(modifySpy.mock.calls.length, 1); - assert.deepStrictEqual(modifySpy.mock.calls[0].arguments, [mockAppId, cmd]); - - assert.ok((await scm.disableSlashCommand('testing-cmd')) === undefined); - assert.strictEqual(disableSpy.mock.calls.length, 1); - assert.deepStrictEqual(disableSpy.mock.calls[0].arguments, [mockAppId, 'testing-cmd']); - - assert.ok((await scm.enableSlashCommand('testing-cmd')) === undefined); - assert.strictEqual(enableSpy.mock.calls.length, 1); - assert.deepStrictEqual(enableSpy.mock.calls[0].arguments, [mockAppId, 'testing-cmd']); - }); -}); diff --git a/packages/apps/tests/server/accessors/UserBuilder.test.ts b/packages/apps/tests/server/accessors/UserBuilder.test.ts deleted file mode 100644 index 028fff0d7f802..0000000000000 --- a/packages/apps/tests/server/accessors/UserBuilder.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { IUser, IUserEmail } from '@rocket.chat/apps-engine/definition/users'; - -import { UserBuilder } from '../../../src/server/accessors'; - -describe('UserBuilder', () => { - it('basicUserBuilder', () => { - assert.doesNotThrow(() => new UserBuilder()); - }); - - it('settingOnUserBuilder', () => { - const ubOnce = new UserBuilder(); - assert.strictEqual(ubOnce.setData({ name: 'Test User', email: 'testuser@gmail.com', username: 'testuser' } as Partial), ubOnce); - assert.strictEqual((ubOnce as any).user.name, 'Test User'); - assert.strictEqual((ubOnce as any).user.username, 'testuser'); - assert.strictEqual((ubOnce as any).user.email, 'testuser@gmail.com'); - - const user: Partial = {} as Partial; - const ub = new UserBuilder(user); - - assert.strictEqual( - ub.setEmails([ - { - address: 'testuser@gmail.com', - verified: false, - } as IUserEmail, - ]), - ub, - ); - assert.deepStrictEqual(user.emails, [ - { - address: 'testuser@gmail.com', - verified: false, - } as IUserEmail, - ]); - assert.deepStrictEqual(ub.getEmails(), [ - { - address: 'testuser@gmail.com', - verified: false, - } as IUserEmail, - ]); - - assert.strictEqual(ub.setDisplayName('Test User'), ub); - assert.deepStrictEqual(user.name, 'Test User'); - assert.deepStrictEqual(ub.getDisplayName(), 'Test User'); - - assert.strictEqual(ub.setUsername('testuser'), ub); - assert.deepStrictEqual(user.username, 'testuser'); - assert.deepStrictEqual(ub.getUsername(), 'testuser'); - - assert.strictEqual(ub.setRoles(['bot']), ub); - assert.deepStrictEqual(user.roles, ['bot']); - assert.deepStrictEqual(ub.getRoles(), ['bot']); - - assert.strictEqual(ub.getUser(), user); - }); -}); diff --git a/packages/apps/tests/server/accessors/UserRead.test.ts b/packages/apps/tests/server/accessors/UserRead.test.ts deleted file mode 100644 index 276e293fa5179..0000000000000 --- a/packages/apps/tests/server/accessors/UserRead.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { IUser } from '@rocket.chat/apps-engine/definition/users'; - -import { UserRead } from '../../../src/server/accessors'; -import type { UserBridge } from '../../../src/server/bridges'; -import { TestData } from '../../test-data/utilities'; - -describe('UserRead', () => { - const user = TestData.getUser(); - const roomIds = ['room-1', 'room-2']; - const mockAppId = 'test-appId'; - - const mockUserBridge = { - doGetById(id: string, appId: string): Promise { - return Promise.resolve(user); - }, - doGetByUsername(id: string, appId: string): Promise { - return Promise.resolve(user); - }, - doGetAppUser(appId?: string): Promise { - return Promise.resolve(user); - }, - doGetUserRoomIds(userId: string): Promise> { - return Promise.resolve(roomIds); - }, - } as unknown as UserBridge; - - it('expectDataFromUserRead', async () => { - assert.doesNotThrow(() => new UserRead(mockUserBridge, 'testing-app')); - - const ur = new UserRead(mockUserBridge, 'testing-app'); - - assert.ok((await ur.getById('fake')) !== undefined); - assert.deepStrictEqual(await ur.getById('fake'), user); - - assert.ok((await ur.getByUsername('username')) !== undefined); - assert.deepStrictEqual(await ur.getByUsername('username'), user); - - assert.ok((await ur.getAppUser(mockAppId)) !== undefined); - assert.deepStrictEqual(await ur.getAppUser(mockAppId), user); - assert.deepStrictEqual(await ur.getAppUser(), user); - assert.deepStrictEqual(await ur.getUserRoomIds(user.id), roomIds); - }); -}); diff --git a/packages/apps/tests/server/accessors/VideoConfProviderExtend.test.ts b/packages/apps/tests/server/accessors/VideoConfProviderExtend.test.ts deleted file mode 100644 index 4a4077b7a8fb9..0000000000000 --- a/packages/apps/tests/server/accessors/VideoConfProviderExtend.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { IVideoConfProvider } from '@rocket.chat/apps-engine/definition/videoConfProviders'; - -import { VideoConfProviderExtend } from '../../../src/server/accessors'; -import type { AppVideoConfProviderManager } from '../../../src/server/managers'; - -describe('VideoConfProviderExtend', () => { - it('basicVideoConfProviderExtend', () => { - assert.doesNotThrow(() => new VideoConfProviderExtend({} as AppVideoConfProviderManager, 'testing')); - }); - - it('provideProviderToVideoConfProviderExtend', async () => { - let providerAdded: IVideoConfProvider | undefined; - const mockManager: AppVideoConfProviderManager = { - addProvider(appId: string, provider: IVideoConfProvider) { - providerAdded = provider; - }, - } as AppVideoConfProviderManager; - - const se = new VideoConfProviderExtend(mockManager, 'testing'); - - const mockProvider: IVideoConfProvider = { - name: 'test', - - async generateUrl(): Promise { - return ''; - }, - async customizeUrl(): Promise { - return ''; - }, - } as IVideoConfProvider; - - await assert.doesNotReject(() => se.provideVideoConfProvider(mockProvider)); - assert.strictEqual(providerAdded, mockProvider); - }); -}); diff --git a/packages/apps/tests/server/accessors/VideoConferenceBuilder.test.ts b/packages/apps/tests/server/accessors/VideoConferenceBuilder.test.ts deleted file mode 100644 index 1d8bb9f8323ac..0000000000000 --- a/packages/apps/tests/server/accessors/VideoConferenceBuilder.test.ts +++ /dev/null @@ -1,101 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { AppVideoConference } from '@rocket.chat/apps-engine/definition/videoConferences'; - -import { VideoConferenceBuilder } from '../../../src/server/accessors'; -import { TestData } from '../../test-data/utilities'; - -describe('VideoConferenceBuilder', () => { - it('basicVideoConferenceBuilderBuilder', () => { - assert.doesNotThrow(() => new VideoConferenceBuilder()); - assert.doesNotThrow(() => new VideoConferenceBuilder(TestData.getAppVideoConference())); - }); - - it('setData', () => { - const builder = new VideoConferenceBuilder(); - - assert.strictEqual(builder.setData({ providerName: 'test-provider' } as AppVideoConference), builder); - assert.strictEqual(((builder as any).call as AppVideoConference).providerName, 'test-provider'); - }); - - it('setRoomId', () => { - const call = {} as AppVideoConference; - const builder = new VideoConferenceBuilder(call); - - assert.strictEqual(builder.setRoomId('roomId'), builder); - assert.strictEqual(call.rid, 'roomId'); - assert.strictEqual(builder.getRoomId(), 'roomId'); - - assert.strictEqual(builder.getVideoConference(), call); - }); - - it('setCreatedBy', () => { - const call = {} as AppVideoConference; - const builder = new VideoConferenceBuilder(call); - - assert.strictEqual(builder.setCreatedBy('userId'), builder); - assert.strictEqual(call.createdBy, 'userId'); - assert.strictEqual(builder.getCreatedBy(), 'userId'); - - assert.strictEqual(builder.getVideoConference(), call); - }); - - it('setProviderName', () => { - const call = {} as AppVideoConference; - const builder = new VideoConferenceBuilder(call); - - assert.strictEqual(builder.setProviderName('test'), builder); - assert.strictEqual(call.providerName, 'test'); - assert.strictEqual(builder.getProviderName(), 'test'); - - assert.strictEqual(builder.getVideoConference(), call); - }); - - it('setProviderData', () => { - const call = {} as AppVideoConference; - const builder = new VideoConferenceBuilder(call); - - assert.strictEqual(builder.setProviderData({ custom: true }), builder); - assert.deepStrictEqual(call.providerData, { custom: true }); - assert.deepStrictEqual(builder.getProviderData(), { custom: true }); - - assert.strictEqual(builder.getVideoConference(), call); - }); - - it('setTitle', () => { - const call = {} as AppVideoConference; - const builder = new VideoConferenceBuilder(call); - - assert.strictEqual(builder.setTitle('Video Conference'), builder); - assert.strictEqual(call.title, 'Video Conference'); - assert.strictEqual(builder.getTitle(), 'Video Conference'); - - assert.strictEqual(builder.getVideoConference(), call); - }); - - it('setDiscussionRid', () => { - const call = {} as AppVideoConference; - const builder = new VideoConferenceBuilder(call); - - assert.strictEqual(builder.setDiscussionRid('testId'), builder); - assert.strictEqual(call.discussionRid, 'testId'); - assert.strictEqual(builder.getDiscussionRid(), 'testId'); - - assert.strictEqual(builder.getVideoConference(), call); - }); - - it('initialData', () => { - const call = { providerName: 'test' } as AppVideoConference; - const builder = new VideoConferenceBuilder(call); - - assert.strictEqual(call.providerName, 'test'); - assert.strictEqual(builder.getProviderName(), 'test'); - - assert.strictEqual(builder.setProviderName('test2'), builder); - assert.strictEqual(call.providerName, 'test2'); - assert.strictEqual(builder.getProviderName(), 'test2'); - - assert.strictEqual(builder.getVideoConference(), call); - }); -}); diff --git a/packages/apps/tests/server/accessors/VideoConferenceExtend.test.ts b/packages/apps/tests/server/accessors/VideoConferenceExtend.test.ts deleted file mode 100644 index 20e317c2ae6d5..0000000000000 --- a/packages/apps/tests/server/accessors/VideoConferenceExtend.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { VideoConference } from '@rocket.chat/apps-engine/definition/videoConferences'; - -import { VideoConferenceExtender } from '../../../src/server/accessors'; -import { TestData } from '../../test-data/utilities'; - -describe('VideoConferenceExtend', () => { - it('basicVideoConferenceExtend', () => { - assert.doesNotThrow(() => new VideoConferenceExtender({} as VideoConference)); - assert.doesNotThrow(() => new VideoConferenceExtender(TestData.getVideoConference())); - }); - - it('setProviderData', () => { - const call = {} as VideoConference; - const extend = new VideoConferenceExtender(call); - - assert.strictEqual(call.providerData, undefined); - assert.strictEqual(extend.setProviderData({ key: 'test' }), extend); - assert.ok(call.providerData !== undefined); - assert.strictEqual(call.providerData.key, 'test'); - - assert.notStrictEqual(extend.getVideoConference(), call); - assert.deepStrictEqual(extend.getVideoConference(), call); - }); - - it('setStatus', () => { - const call = { status: 0 } as VideoConference; - const extend = new VideoConferenceExtender(call); - - assert.strictEqual(call.status, 0); - assert.strictEqual(extend.setStatus(1), extend); - assert.strictEqual(call.status, 1); - }); - - it('setEndedBy', () => { - const call = {} as VideoConference; - const extend = new VideoConferenceExtender(call); - - assert.strictEqual(call.endedBy, undefined); - assert.strictEqual(extend.setEndedBy('userId'), extend); - assert.ok(call.endedBy !== undefined); - assert.strictEqual(call.endedBy._id, 'userId'); - }); - - it('setEndedAt', () => { - const call = {} as VideoConference; - const extend = new VideoConferenceExtender(call); - - const date = new Date(); - - assert.strictEqual(call.endedAt, undefined); - assert.strictEqual(extend.setEndedAt(date), extend); - assert.strictEqual(call.endedAt, date); - }); - - it('setDiscussionRid', () => { - const call = {} as VideoConference; - const extend = new VideoConferenceExtender(call); - - assert.strictEqual(call.discussionRid, undefined); - assert.strictEqual(extend.setDiscussionRid('testId'), extend); - assert.strictEqual(call.discussionRid, 'testId'); - }); - - it('addUser', () => { - const call = { users: [] } as VideoConference; - const extend = new VideoConferenceExtender(call); - - assert.strictEqual(call.users.length, 0); - assert.strictEqual(extend.addUser('userId'), extend); - assert.ok(call.users.length > 0); - assert.strictEqual(call.users[0]._id, 'userId'); - }); -}); diff --git a/packages/apps/tests/server/accessors/VideoConferenceRead.test.ts b/packages/apps/tests/server/accessors/VideoConferenceRead.test.ts deleted file mode 100644 index 478e92a1df91b..0000000000000 --- a/packages/apps/tests/server/accessors/VideoConferenceRead.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import type { VideoConference } from '@rocket.chat/apps-engine/definition/videoConferences'; - -import { VideoConferenceRead } from '../../../src/server/accessors'; -import type { VideoConferenceBridge } from '../../../src/server/bridges'; -import { TestData } from '../../test-data/utilities'; - -describe('VideoConferenceRead', () => { - it('expectDataFromVideoConferenceRead', async () => { - const videoConference = TestData.getVideoConference(); - - const call = videoConference; - const mockVideoConfBridge = { - doGetById(id, appId): Promise { - return Promise.resolve(call); - }, - } as VideoConferenceBridge; - - assert.doesNotThrow(() => new VideoConferenceRead(mockVideoConfBridge, 'testing-app')); - - const read = new VideoConferenceRead(mockVideoConfBridge, 'testing-app'); - - assert.ok((await read.getById('fake')) !== undefined); - assert.strictEqual(await read.getById('fake'), videoConference); - }); -}); diff --git a/packages/apps/tests/server/managers/AppAccessorManager.test.ts b/packages/apps/tests/server/managers/AppAccessorManager.test.ts deleted file mode 100644 index ba98152dd2f8a..0000000000000 --- a/packages/apps/tests/server/managers/AppAccessorManager.test.ts +++ /dev/null @@ -1,174 +0,0 @@ -import * as assert from 'node:assert'; -import { describe, it, beforeEach, afterEach, mock } from 'node:test'; - -import type { AppManager } from '../../../src/server/AppManager'; -import type { ProxiedApp } from '../../../src/server/ProxiedApp'; -import type { AppBridges } from '../../../src/server/bridges'; -import type { - AppApiManager, - AppExternalComponentManager, - AppSchedulerManager, - AppSlashCommandManager, - AppVideoConfProviderManager, -} from '../../../src/server/managers'; -import { AppAccessorManager } from '../../../src/server/managers'; -import type { AppOutboundCommunicationProviderManager } from '../../../src/server/managers/AppOutboundCommunicationProviderManager'; -import type { UIActionButtonManager } from '../../../src/server/managers/UIActionButtonManager'; -import { TestsAppBridges } from '../../test-data/bridges/appBridges'; - -describe('AppAccessorManager', () => { - let bridges: AppBridges; - let manager: AppManager; - let spies: { - getServerSettingBridge: any; - getEnvironmentalVariableBridge: any; - getMessageBridge: any; - getPersistenceBridge: any; - getRoomBridge: any; - getUserBridge: any; - getBridges: any; - getCommandManager: any; - getExternalComponentManager: any; - getApiManager: any; - }; - - beforeEach(() => { - bridges = new TestsAppBridges(); - - const brds = bridges; - manager = { - getBridges() { - return brds; - }, - getCommandManager() { - return {} as AppSlashCommandManager; - }, - getExternalComponentManager() { - return {} as AppExternalComponentManager; - }, - getApiManager() { - return {} as AppApiManager; - }, - getOneById(appId: string): ProxiedApp { - return appId === 'testing' ? ({} as ProxiedApp) : undefined; - }, - getSchedulerManager() { - return {} as AppSchedulerManager; - }, - getUIActionButtonManager() { - return {} as UIActionButtonManager; - }, - getVideoConfProviderManager() { - return {} as AppVideoConfProviderManager; - }, - getOutboundCommunicationProviderManager() { - return {} as AppOutboundCommunicationProviderManager; - }, - } as unknown as AppManager; - - // Set up spies before each test - spies = { - getServerSettingBridge: mock.method(bridges, 'getServerSettingBridge'), - getEnvironmentalVariableBridge: mock.method(bridges, 'getEnvironmentalVariableBridge'), - getMessageBridge: mock.method(bridges, 'getMessageBridge'), - getPersistenceBridge: mock.method(bridges, 'getPersistenceBridge'), - getRoomBridge: mock.method(bridges, 'getRoomBridge'), - getUserBridge: mock.method(bridges, 'getUserBridge'), - getBridges: mock.method(manager, 'getBridges'), - getCommandManager: mock.method(manager, 'getCommandManager'), - getExternalComponentManager: mock.method(manager, 'getExternalComponentManager'), - getApiManager: mock.method(manager, 'getApiManager'), - }; - }); - - afterEach(() => { - mock.restoreAll(); - }); - - it('basicAppAccessorManager', () => { - assert.doesNotThrow(() => new AppAccessorManager(manager)); - assert.doesNotThrow(() => new AppAccessorManager(manager).purifyApp('testing')); - }); - - it('configurationExtend', () => { - const acm = new AppAccessorManager(manager); - - assert.ok(acm.getConfigurationExtend('testing')); - assert.throws(() => acm.getConfigurationExtend('fake'), { - name: 'Error', - message: 'No App found by the provided id: fake', - }); - assert.ok(acm.getConfigurationExtend('testing')); - - assert.strictEqual(spies.getExternalComponentManager.mock.calls.length, 1); - assert.strictEqual(spies.getCommandManager.mock.calls.length, 1); - assert.strictEqual(spies.getApiManager.mock.calls.length, 1); - }); - - it('environmentRead', () => { - const acm = new AppAccessorManager(manager); - - assert.ok(acm.getEnvironmentRead('testing')); - assert.throws(() => acm.getEnvironmentRead('fake'), { - name: 'Error', - message: 'No App found by the provided id: fake', - }); - assert.ok(acm.getEnvironmentRead('testing')); - - assert.strictEqual(spies.getServerSettingBridge.mock.calls.length, 1); - assert.strictEqual(spies.getEnvironmentalVariableBridge.mock.calls.length, 1); - }); - - it('configurationModify', () => { - const acm = new AppAccessorManager(manager); - - assert.ok(acm.getConfigurationModify('testing')); - assert.ok(acm.getConfigurationModify('testing')); - - assert.strictEqual(spies.getServerSettingBridge.mock.calls.length, 1); - assert.strictEqual(spies.getCommandManager.mock.calls.length, 1); - }); - - it('reader', () => { - const acm = new AppAccessorManager(manager); - - assert.ok(acm.getReader('testing')); - assert.ok(acm.getReader('testing')); - - assert.strictEqual(spies.getServerSettingBridge.mock.calls.length, 1); - assert.strictEqual(spies.getEnvironmentalVariableBridge.mock.calls.length, 1); - assert.strictEqual(spies.getPersistenceBridge.mock.calls.length, 1); - assert.strictEqual(spies.getRoomBridge.mock.calls.length, 1); - assert.strictEqual(spies.getUserBridge.mock.calls.length, 2); - assert.strictEqual(spies.getMessageBridge.mock.calls.length, 2); - }); - - it('modifier', () => { - const acm = new AppAccessorManager(manager); - - assert.ok(acm.getModifier('testing')); - assert.ok(acm.getModifier('testing')); - - assert.strictEqual(spies.getBridges.mock.calls.length, 1); - assert.strictEqual(spies.getMessageBridge.mock.calls.length, 1); - }); - - it('persistence', () => { - const acm = new AppAccessorManager(manager); - - assert.ok(acm.getPersistence('testing')); - assert.ok(acm.getPersistence('testing')); - - assert.strictEqual(spies.getPersistenceBridge.mock.calls.length, 1); - }); - - it('http', () => { - const acm = new AppAccessorManager(manager); - - assert.ok(acm.getHttp('testing')); - assert.ok(acm.getHttp('testing')); - - (acm as any).https.delete('testing'); - assert.ok(acm.getHttp('testing')); - }); -}); diff --git a/packages/apps/tests/server/managers/AppApiManager.test.ts b/packages/apps/tests/server/managers/AppApiManager.test.ts index 9437a6ffea674..0e3d15513fd34 100644 --- a/packages/apps/tests/server/managers/AppApiManager.test.ts +++ b/packages/apps/tests/server/managers/AppApiManager.test.ts @@ -13,7 +13,7 @@ import type { AppSlashCommandManager, AppVideoConfProviderManager, } from '../../../src/server/managers'; -import { AppAccessorManager, AppApiManager } from '../../../src/server/managers'; +import { AppApiManager } from '../../../src/server/managers'; import { AppApi } from '../../../src/server/managers/AppApi'; import type { UIActionButtonManager } from '../../../src/server/managers/UIActionButtonManager'; import type { AppLogStorage, IAppStorageItem } from '../../../src/server/storage'; @@ -24,7 +24,6 @@ import { TestData } from '../../test-data/utilities'; describe('AppApiManager', () => { let mockBridges: TestsAppBridges; let mockApp: ProxiedApp; - let mockAccessors: AppAccessorManager; let mockManager: AppManager; beforeEach(() => { @@ -63,12 +62,6 @@ describe('AppApiManager', () => { return {} as AppVideoConfProviderManager; }, } as AppManager; - - mockAccessors = new AppAccessorManager(mockManager); - const ac = mockAccessors; - mockManager.getAccessorManager = function _getAccessorManager(): AppAccessorManager { - return ac; - }; }); afterEach(() => { @@ -82,7 +75,6 @@ describe('AppApiManager', () => { const ascm = new AppApiManager(mockManager); assert.strictEqual((ascm as any).manager, mockManager); assert.strictEqual((ascm as any).bridge, mockBridges.getApiBridge()); - assert.strictEqual((ascm as any).accessors, mockManager.getAccessorManager()); assert.ok((ascm as any).providedApis !== undefined); assert.strictEqual((ascm as any).providedApis.size, 0); }); diff --git a/packages/apps/tests/server/managers/AppListenerManager.test.ts b/packages/apps/tests/server/managers/AppListenerManager.test.ts index 6bb43f31d4262..1ab2198342eff 100644 --- a/packages/apps/tests/server/managers/AppListenerManager.test.ts +++ b/packages/apps/tests/server/managers/AppListenerManager.test.ts @@ -20,7 +20,6 @@ describe('AppListenerManager', () => { } as ProxiedApp; const mockManager = { - getAccessorManager() {}, getOneById(appId: string) { return mockApp; }, diff --git a/packages/apps/tests/server/managers/AppOutboundCommunicationProviderManager.test.ts b/packages/apps/tests/server/managers/AppOutboundCommunicationProviderManager.test.ts index a025ab297c9b7..424b44f905a0b 100644 --- a/packages/apps/tests/server/managers/AppOutboundCommunicationProviderManager.test.ts +++ b/packages/apps/tests/server/managers/AppOutboundCommunicationProviderManager.test.ts @@ -5,7 +5,7 @@ import type { AppManager } from '../../../src/server/AppManager'; import type { ProxiedApp } from '../../../src/server/ProxiedApp'; import type { AppBridges } from '../../../src/server/bridges'; import type { AppApiManager, AppExternalComponentManager, AppSchedulerManager, AppSlashCommandManager } from '../../../src/server/managers'; -import { AppAccessorManager, AppOutboundCommunicationProviderManager } from '../../../src/server/managers'; +import { AppOutboundCommunicationProviderManager } from '../../../src/server/managers'; import { OutboundMessageProvider } from '../../../src/server/managers/AppOutboundCommunicationProvider'; import { AppPermissionManager } from '../../../src/server/managers/AppPermissionManager'; import type { UIActionButtonManager } from '../../../src/server/managers/UIActionButtonManager'; @@ -17,7 +17,6 @@ import { TestData } from '../../test-data/utilities'; describe('AppOutboundCommunicationProviderManager', () => { let mockBridges: TestsAppBridges; let mockApp: ProxiedApp; - let mockAccessors: AppAccessorManager; let mockManager: AppManager; let hasPermissionSpy: ReturnType; @@ -59,12 +58,6 @@ describe('AppOutboundCommunicationProviderManager', () => { }, } as AppManager; - mockAccessors = new AppAccessorManager(mockManager); - const ac = mockAccessors; - mockManager.getAccessorManager = function _getAccessorManager(): AppAccessorManager { - return ac; - }; - hasPermissionSpy = mock.method(AppPermissionManager, 'hasPermission', () => true); }); @@ -78,7 +71,6 @@ describe('AppOutboundCommunicationProviderManager', () => { const manager = new AppOutboundCommunicationProviderManager(mockManager); assert.strictEqual((manager as any).manager, mockManager); - assert.strictEqual((manager as any).accessors, mockManager.getAccessorManager()); assert.ok((manager as any).outboundMessageProviders !== undefined); assert.strictEqual((manager as any).outboundMessageProviders.size, 0); }); diff --git a/packages/apps/tests/server/managers/AppSettingsManager.test.ts b/packages/apps/tests/server/managers/AppSettingsManager.test.ts index 83f2fd28b53dc..9bb2c5a589cca 100644 --- a/packages/apps/tests/server/managers/AppSettingsManager.test.ts +++ b/packages/apps/tests/server/managers/AppSettingsManager.test.ts @@ -14,7 +14,7 @@ import type { AppSlashCommandManager, AppVideoConfProviderManager, } from '../../../src/server/managers'; -import { AppAccessorManager, AppSettingsManager } from '../../../src/server/managers'; +import { AppSettingsManager } from '../../../src/server/managers'; import type { UIActionButtonManager } from '../../../src/server/managers/UIActionButtonManager'; import type { AppMetadataStorage, IAppStorageItem } from '../../../src/server/storage'; import { TestsAppBridges } from '../../test-data/bridges/appBridges'; @@ -24,7 +24,6 @@ describe('AppSettingsManager', () => { let mockStorageItem: IAppStorageItem; let mockApp: ProxiedApp; let mockBridges: AppBridges; - let mockAccessors: AppAccessorManager; let mockStorage: AppMetadataStorage; let mockManager: AppManager; @@ -90,12 +89,6 @@ describe('AppSettingsManager', () => { return {} as AppVideoConfProviderManager; }, } as AppManager; - - mockAccessors = new AppAccessorManager(mockManager); - const ac = mockAccessors; - mockManager.getAccessorManager = function _getAccessorManager(): AppAccessorManager { - return ac; - }; }); afterEach(() => { diff --git a/packages/apps/tests/server/managers/AppSlashCommandManager.test.ts b/packages/apps/tests/server/managers/AppSlashCommandManager.test.ts index 53f3086db4f5b..8de894ab4b492 100644 --- a/packages/apps/tests/server/managers/AppSlashCommandManager.test.ts +++ b/packages/apps/tests/server/managers/AppSlashCommandManager.test.ts @@ -13,7 +13,7 @@ import type { AppSchedulerManager, AppVideoConfProviderManager, } from '../../../src/server/managers'; -import { AppAccessorManager, AppSlashCommandManager } from '../../../src/server/managers'; +import { AppSlashCommandManager } from '../../../src/server/managers'; import { AppSlashCommand } from '../../../src/server/managers/AppSlashCommand'; import type { UIActionButtonManager } from '../../../src/server/managers/UIActionButtonManager'; import { Room } from '../../../src/server/rooms/Room'; @@ -25,7 +25,6 @@ import { TestData } from '../../test-data/utilities'; describe('AppSlashCommandManager', () => { let mockBridges: TestsAppBridges; let mockApp: ProxiedApp; - let mockAccessors: AppAccessorManager; let mockManager: AppManager; function setupMocks() { @@ -78,12 +77,6 @@ describe('AppSlashCommandManager', () => { return {} as AppVideoConfProviderManager; }, } as AppManager; - - mockAccessors = new AppAccessorManager(mockManager); - const ac = mockAccessors; - mockManager.getAccessorManager = function _getAccessorManager(): AppAccessorManager { - return ac; - }; }); afterEach(() => { @@ -98,7 +91,6 @@ describe('AppSlashCommandManager', () => { const ascm = new AppSlashCommandManager(mockManager); assert.strictEqual((ascm as any).manager, mockManager); assert.strictEqual((ascm as any).bridge, mockBridges.getCommandBridge()); - assert.strictEqual((ascm as any).accessors, mockManager.getAccessorManager()); assert.ok((ascm as any).providedCommands !== undefined); assert.strictEqual((ascm as any).providedCommands.size, 0); assert.ok((ascm as any).modifiedCommands !== undefined); diff --git a/packages/apps/tests/server/managers/AppVideoConfProviderManager.test.ts b/packages/apps/tests/server/managers/AppVideoConfProviderManager.test.ts index 16265aaa07ffd..a803b54172c37 100644 --- a/packages/apps/tests/server/managers/AppVideoConfProviderManager.test.ts +++ b/packages/apps/tests/server/managers/AppVideoConfProviderManager.test.ts @@ -5,7 +5,7 @@ import type { AppManager } from '../../../src/server/AppManager'; import type { ProxiedApp } from '../../../src/server/ProxiedApp'; import type { AppBridges } from '../../../src/server/bridges'; import type { AppApiManager, AppExternalComponentManager, AppSchedulerManager, AppSlashCommandManager } from '../../../src/server/managers'; -import { AppAccessorManager, AppVideoConfProviderManager } from '../../../src/server/managers'; +import { AppVideoConfProviderManager } from '../../../src/server/managers'; import { AppVideoConfProvider } from '../../../src/server/managers/AppVideoConfProvider'; import type { UIActionButtonManager } from '../../../src/server/managers/UIActionButtonManager'; import type { AppLogStorage, IAppStorageItem } from '../../../src/server/storage'; @@ -16,7 +16,6 @@ import { TestData } from '../../test-data/utilities'; describe('AppVideoConfProviderManager', () => { let mockBridges: TestsAppBridges; let mockApp: ProxiedApp; - let mockAccessors: AppAccessorManager; let mockManager: AppManager; beforeEach(() => { @@ -55,12 +54,6 @@ describe('AppVideoConfProviderManager', () => { return {} as AppVideoConfProviderManager; }, } as AppManager; - - mockAccessors = new AppAccessorManager(mockManager); - const ac = mockAccessors; - mockManager.getAccessorManager = function _getAccessorManager(): AppAccessorManager { - return ac; - }; }); afterEach(() => { @@ -73,7 +66,6 @@ describe('AppVideoConfProviderManager', () => { const manager = new AppVideoConfProviderManager(mockManager); assert.strictEqual((manager as any).manager, mockManager); - assert.strictEqual((manager as any).accessors, mockManager.getAccessorManager()); assert.ok((manager as any).videoConfProviders !== undefined); assert.strictEqual((manager as any).videoConfProviders.size, 0); }); diff --git a/packages/apps/tests/server/runtime/DenoRuntimeSubprocessController.test.ts b/packages/apps/tests/server/runtime/DenoRuntimeSubprocessController.test.ts index d9cbd3e530f67..2a80dbb553886 100644 --- a/packages/apps/tests/server/runtime/DenoRuntimeSubprocessController.test.ts +++ b/packages/apps/tests/server/runtime/DenoRuntimeSubprocessController.test.ts @@ -10,7 +10,7 @@ import { type RpcStatusType, SuccessObject } from 'jsonrpc-lite'; import type { AppManager } from '../../../src/server/AppManager'; import type { IParseAppPackageResult } from '../../../src/server/compiler'; -import { AppAccessorManager, AppApiManager } from '../../../src/server/managers'; +import { AppApiManager } from '../../../src/server/managers'; import { DenoRuntimeSubprocessController } from '../../../src/server/runtime/deno/AppsEngineDenoRuntime'; import type { IAppStorageItem } from '../../../src/server/storage'; import { TestInfastructureSetup } from '../../test-data/utilities'; @@ -28,9 +28,6 @@ describe('DenoRuntimeSubprocessController', () => { const infrastructure = new TestInfastructureSetup(); manager = infrastructure.getMockManager(); - const accessors = new AppAccessorManager(manager); - manager.getAccessorManager = () => accessors; - const api = new AppApiManager(manager); manager.getApiManager = () => api; diff --git a/packages/apps/tests/server/runtime/SecureFieldsCodecCompatibility.test.ts b/packages/apps/tests/server/runtime/SecureFieldsCodecCompatibility.test.ts index 869442e4121d4..cde673951c2ad 100644 --- a/packages/apps/tests/server/runtime/SecureFieldsCodecCompatibility.test.ts +++ b/packages/apps/tests/server/runtime/SecureFieldsCodecCompatibility.test.ts @@ -10,7 +10,7 @@ import { RoomType } from '@rocket.chat/apps-engine/definition/rooms'; import { kSecureFields } from '../../../src/lib/SecureFields'; import type { AppManager } from '../../../src/server/AppManager'; import type { IParseAppPackageResult } from '../../../src/server/compiler'; -import { AppAccessorManager, AppApiManager } from '../../../src/server/managers'; +import { AppApiManager } from '../../../src/server/managers'; import { DenoRuntimeSubprocessController } from '../../../src/server/runtime/deno/AppsEngineDenoRuntime'; import type { IAppStorageItem } from '../../../src/server/storage'; import { TestInfastructureSetup } from '../../test-data/utilities'; @@ -75,9 +75,6 @@ describe('@@SecureFields codec compatibility (Node → Deno)', () => { const infrastructure = new TestInfastructureSetup(); const manager = infrastructure.getMockManager(); - const accessors = new AppAccessorManager(manager); - manager.getAccessorManager = () => accessors; - const api = new AppApiManager(manager); manager.getApiManager = () => api;