Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 48 additions & 12 deletions apps/meteor/MIGRATION_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ apps/meteor/server/
│ ├── ApiClass.ts # API framework
│ ├── api.ts # API initialization
│ ├── router.ts # Hono router
│ └── definition.ts # TypeScript types
│ ├── definition.ts # TypeScript types
│ └── webhooks.ts # /hooks/* webhook API (from app/integrations/server/api/)
├── slashcommands/ # Slash commands (from app/slashcommands-*/server/)
│ ├── archiveroom.ts
Expand Down Expand Up @@ -102,6 +103,7 @@ apps/meteor/server/
│ ├── platform/ # from app/autotranslate/ + app/e2e/ + existing flat files
│ ├── import/ # from app/importer/server/methods/
│ ├── integrations/ # from app/integrations/server/methods/
│ ├── media/ # from app/custom-sounds/, app/emoji-custom/, app/file-upload/ methods (Phase 6e)
│ └── index.ts # updated to import from domain subfolders
├── hooks/ # EXISTING — event handlers
Expand Down Expand Up @@ -397,6 +399,8 @@ Each phase produces a manifest file (the tables below), feeds it to `move-batch.

**Note**: After the rename above, the existing flat files (now under `server/meteor-methods/`) are also moved into the appropriate domain subfolder as part of this phase.

**Deferred methods**: features that move wholesale in Phases 6/7 (file-upload, mentions, user-status, emoji-custom, custom-sounds, push-notifications, statistics, version-check, meteor-accounts-saml, oauth2-server-config) keep their `methods/` dirs until their own phase. Those dirs are routed to `server/meteor-methods/<domain>/` by explicit rows in the Phase 6/7 tables — they must not ride along into `server/lib/`. Until then, `verify-no-old-imports.mjs "server/methods"` reports ~11 hits pointing at these dirs; that is expected.

| Source | Destination |
| ------------------------------------------------- | ----------------------------------------------- |
| `app/lib/server/methods/setRealName.ts` | `server/meteor-methods/users/setRealName.ts` |
Expand Down Expand Up @@ -494,6 +498,19 @@ Each phase produces a manifest file (the tables below), feeds it to `move-batch.

**Verification**: `yarn lint --quiet`, test several Meteor methods via DDP client.

**Registration audit (mandatory here and in Phases 6/7).** A method file that loses its side-effect import silently stops registering — lint, tsc and the unit suites all stay green, and e2e only exercises ~24 methods by name (`methodCall` helper), so most drops are invisible to CI. Many methods also have **no in-repo caller** (they serve mobile/DDP clients), so no repo test can ever catch them. After every batch that touches method files, verify that **every** non-empty file under `server/meteor-methods/` (and `ee/server/meteor-methods/`) is imported by the aggregator index or by a named-import consumer:

```sh
for f in $(find server/meteor-methods ee/server/meteor-methods -name "*.ts" ! -name "*.spec.ts" | grep -v "^server/meteor-methods/index.ts$"); do
sub="${f%.ts}"; sub="${sub#*meteor-methods/}"
grep -rql --include="*.ts" "meteor-methods/${sub}'" server app ee client imports lib | grep -qv "^${f}$" \
|| grep -q "'\./${sub}'" server/meteor-methods/index.ts \
|| echo "UNREGISTERED: $f"
done
```

Match against the full `meteor-methods/<subpath>` suffix — a loose `<domain>/<name>` pattern false-passes on same-named `server/lib/` functions (this exact aliasing hid a dropped `unblockUser` registration in Phase 5b until audited). The audit must come back empty: the two historical 0-byte stragglers it initially flagged (`saveBusinessHour.ts`, EE `removeBusinessHour.ts`, emptied but not deleted by #37772/#37819) were removed in Phase 5.

---

### Phase 6: Lib, Hooks, and Feature-Specific Code
Expand All @@ -504,6 +521,8 @@ Each phase produces a manifest file (the tables below), feeds it to `move-batch.

**Scope**: ~300 files

**Methods stay out of `lib/`.** Several features in this phase still carry a `methods/` subdir that Phase 5 deliberately did not touch (their features move here). Those files go to `server/meteor-methods/<domain>/` — never along with the feature into `server/lib/` — so the "all Meteor methods live in `meteor-methods/`" invariant from Phase 5 holds. Every such dir is listed explicitly in the tables below, and the parent row is qualified with "(non-methods)". This phase introduces one new domain folder, `server/meteor-methods/media/`, for media admin methods (custom sounds, custom emoji, file-upload helpers).

#### Phase 6a: Auth Providers (~30 files)

| Source | Destination |
Expand All @@ -520,7 +539,8 @@ Each phase produces a manifest file (the tables below), feeds it to `move-batch.
| `app/iframe-login/server/` | `server/lib/auth-providers/iframe.ts` |
| `app/wordpress/server/` | `server/lib/auth-providers/wordpress.ts` |
| `app/lib/server/oauth/*.js` | `server/lib/auth-providers/oauth/` |
| `app/meteor-accounts-saml/server/` | `server/lib/saml/` |
| `app/meteor-accounts-saml/server/` (non-methods) | `server/lib/saml/` |
| `app/meteor-accounts-saml/server/methods/*.ts` | `server/meteor-methods/auth/` |
| `app/2fa/server/` (non-methods) | `server/lib/2fa/` |
| `app/authentication/server/` (non-hooks) | `server/lib/auth/` |
| `app/token-login/server/` | `server/lib/auth/token-login.ts` |
Expand All @@ -543,7 +563,8 @@ Each phase produces a manifest file (the tables below), feeds it to `move-batch.
| Source | Destination |
| -------------------------------- | ----------------------------------------- |
| `app/push/server/` | `server/lib/notifications/push/` |
| `app/push-notifications/server/` | `server/lib/notifications/push-config/` |
| `app/push-notifications/server/` (non-methods) | `server/lib/notifications/push-config/` |
| `app/push-notifications/server/methods/saveNotificationSettings.ts` | `server/meteor-methods/users/` |
| `app/mailer/server/` | `server/lib/notifications/email/` |
| `app/mail-messages/server/` | `server/lib/notifications/mail-messages/` |
| `app/notification-queue/server/` | `server/lib/notifications/queue/` |
Expand All @@ -559,19 +580,25 @@ Each phase produces a manifest file (the tables below), feeds it to `move-batch.
| `app/message-pin/server/` | `server/lib/messaging/pins/` |
| `app/message-star/server/` | `server/lib/messaging/stars/` |
| `app/message-mark-as-unread/server/` | `server/lib/messaging/unread/` |
| `app/mentions/server/` | `server/lib/messaging/mentions/` |
| `app/mentions/server/` (non-methods) | `server/lib/messaging/mentions/` |
| `app/mentions/server/methods/getUserMentionsByChannel.ts` | `server/meteor-methods/messages/` |
| `app/markdown/server/` | `server/lib/messaging/markdown/` |
| `app/emoji/server/` | `server/lib/messaging/emoji/` |

#### Phase 6e: Media, Import, Search, and Remaining Libraries

| Source | Destination |
| ------------------------------------------- | ----------------------------------------- |
| `app/file-upload/server/` | `server/lib/media/file-upload/` |
| `app/file-upload/server/` (non-methods) | `server/lib/media/file-upload/` |
| `app/file-upload/server/methods/sendFileMessage.ts` (+ co-located `.spec.ts`) | `server/meteor-methods/messages/` |
| `app/file-upload/server/methods/getS3FileUrl.ts` | `server/meteor-methods/media/` |
| `app/file-upload/server/methods/isImagePreviewSupported.ts` | `server/meteor-methods/media/` |
| `app/file/server/` | `server/lib/media/file/` |
| `app/emoji-custom/server/` | `server/lib/media/emoji-custom/` |
| `app/emoji-custom/server/` (non-methods) | `server/lib/media/emoji-custom/` |
| `app/emoji-custom/server/methods/*.ts` | `server/meteor-methods/media/` |
| `app/emoji-emojione/server/` | `server/lib/media/emoji-emojione/` |
| `app/custom-sounds/server/` | `server/lib/media/custom-sounds/` |
| `app/custom-sounds/server/` (non-methods) | `server/lib/media/custom-sounds/` |
| `app/custom-sounds/server/methods/*.ts` | `server/meteor-methods/media/` |
| `app/assets/server/` | `server/lib/media/assets/` |
| `app/importer/server/` (non-methods) | `server/lib/import/` |
| `app/importer-csv/server/` | `server/lib/import/csv/` |
Expand All @@ -583,13 +610,20 @@ Each phase produces a manifest file (the tables below), feeds it to `move-batch.
| `app/search/server/` | `server/lib/search/` |
| `app/autotranslate/server/` (non-methods) | `server/lib/autotranslate/` |
| `app/e2e/server/` (non-methods) | `server/lib/e2e/` |
| `app/integrations/server/` (non-methods) | `server/lib/integrations/` |
| `app/statistics/server/` | `server/lib/statistics/` |
| `app/integrations/server/` (non-methods, non-api) | `server/lib/integrations/` |
| `app/integrations/server/api/api.ts` | `server/api/webhooks.ts` |
| `app/statistics/server/` (non-methods) | `server/lib/statistics/` |
| `app/statistics/server/methods/getStatistics.ts` | `server/meteor-methods/platform/` |
| `app/metrics/server/` | `server/lib/metrics/` |
| `app/cloud/server/` (non-functions) | `server/lib/cloud/` |
| `app/version-check/server/` | `server/lib/cloud/version-check/` |
| `app/version-check/server/` (non-methods) | `server/lib/cloud/version-check/` |
| `app/version-check/server/methods/banner_dismiss.ts` | `server/meteor-methods/platform/` |
| `app/license/server/` | `server/lib/cloud/license/` |

> `app/integrations/server/api/api.ts` is REST-API responsibility (it builds the `/hooks/*` webhook API on `server/api`'s `APIClass`), so it joins `server/api/` rather than `server/lib/integrations/` — same reasoning that sent the livechat REST endpoints to `server/api/v1/omnichannel/` in Phase 3.
>
> `sendFileMessage.spec.ts` is co-located with its source (not a `tests/unit` mirror) and is a **mocha** spec discovered today by the `app/file-upload/server/**/*.spec.ts` glob. When it moves, add a `server/meteor-methods/**/*.spec.ts` glob to `.mocharc.js`, and re-point the `app/file-upload` glob when the rest of the feature moves — see [Test Mocks and Runner Globs](#test-mocks-and-runner-globs-proxyquire--jestmock--lint--tsc-do-not-catch-these).

**Verification**: `yarn lint --quiet` after each sub-phase, full test suite at end of Phase 6.

---
Expand Down Expand Up @@ -617,11 +651,13 @@ Each phase produces a manifest file (the tables below), feeds it to `move-batch.
- `app/channel-settings/server/` (non-methods) → `server/lib/rooms/settings/`
- `app/invites/server/` → `server/lib/rooms/invites/`
- `app/retention-policy/server/` → `server/lib/rooms/retention/`
- `app/user-status/server/` → `server/lib/users/status/`
- `app/user-status/server/` (non-methods) → `server/lib/users/status/`
- `app/user-status/server/methods/*.ts` (setUserStatus, getUserStatusText, custom-status CRUD) → `server/meteor-methods/users/`
- `app/bot-helpers/server/` → `server/lib/bot-helpers/` (moved in Phase 1)
- `app/cors/server/` → `server/lib/cors/`
- `app/error-handler/server/` → `server/lib/error-handler/`
- `app/oauth2-server-config/server/` → `server/lib/auth/oauth2-server/`
- `app/oauth2-server-config/server/` (non-methods) → `server/lib/auth/oauth2-server/`
- `app/oauth2-server-config/server/admin/methods/*.ts` (deleteOAuthApp, updateOAuthApp) → `server/meteor-methods/auth/`
- `app/settings/server/` → `server/settings/` (merge with existing)
- `app/theme/server/` → `server/settings/theme/`
- `app/utils/server/` → `server/lib/utils/`
Expand Down
5 changes: 0 additions & 5 deletions apps/meteor/app/2fa/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,2 @@
import './MethodInvocationOverride';
import './methods/checkCodesRemaining';
import './methods/disable';
import './methods/enable';
import './methods/regenerateCodes';
import './methods/validateTempToken';
import './loginHandler';
2 changes: 1 addition & 1 deletion apps/meteor/app/apps/server/bridges/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Users, Subscriptions } from '@rocket.chat/models';

import { deleteMessage } from '../../../../server/lib/messages/deleteMessage';
import { updateMessage } from '../../../../server/lib/messages/updateMessage';
import { executeSendMessage } from '../../../lib/server/methods/sendMessage';
import { executeSendMessage } from '../../../../server/meteor-methods/messages/sendMessage';
import notifications from '../../../notifications/server/lib/Notifications';
import { executeSetReaction } from '../../../reactions/server/setReaction';

Expand Down
8 changes: 4 additions & 4 deletions apps/meteor/app/apps/server/bridges/rooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import type { FindOptions, Sort } from 'mongodb';
import { addUserToRoom } from '../../../../server/lib/rooms/addUserToRoom';
import { deleteRoom } from '../../../../server/lib/rooms/deleteRoom';
import { removeUserFromRoom } from '../../../../server/lib/rooms/removeUserFromRoom';
import { createDirectMessage } from '../../../../server/methods/createDirectMessage';
import { createDiscussion } from '../../../discussion/server/methods/createDiscussion';
import { createChannelMethod } from '../../../lib/server/methods/createChannel';
import { createPrivateGroupMethod } from '../../../lib/server/methods/createPrivateGroup';
import { createDirectMessage } from '../../../../server/meteor-methods/messages/createDirectMessage';
import { createDiscussion } from '../../../../server/meteor-methods/messages/createDiscussion';
import { createChannelMethod } from '../../../../server/meteor-methods/rooms/createChannel';
import { createPrivateGroupMethod } from '../../../../server/meteor-methods/rooms/createPrivateGroup';

const rawRoomProjection: FindOptions<ICoreRoom>['projection'] = {
_id: 1,
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/apps/server/bridges/uploads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import type { IUpload } from '@rocket.chat/apps-engine/definition/uploads';
import type { IUploadDetails } from '@rocket.chat/apps-engine/definition/uploads/IUploadDetails';

import { determineFileType } from '../../../../ee/lib/misc/determineFileType';
import { sendFileLivechatMessage } from '../../../../server/meteor-methods/omnichannel/sendFileLivechatMessage';
import { FileUpload } from '../../../file-upload/server';
import { sendFileMessage } from '../../../file-upload/server/methods/sendFileMessage';
import { sendFileLivechatMessage } from '../../../livechat/server/methods/sendFileLivechatMessage';

const getUploadDetails = (details: IUploadDetails): Partial<IUploadDetails> => {
if (details.visitorToken) {
Expand Down
3 changes: 0 additions & 3 deletions apps/meteor/app/authorization/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ import { roomAccessAttributes, canAccessRoomAsync } from '../../../server/lib/au
import { getRoles } from '../../../server/lib/authorization/getRoles';
import { getUsersInRole } from '../../../server/lib/authorization/getUsersInRole';
import { subscriptionHasRole } from '../../../server/lib/authorization/hasRole';
import './methods/addPermissionToRole';
import './methods/addUserToRole';
import './methods/removeRoleFromPermission';
import './streamer/permissions';

export { getRoles, getUsersInRole, subscriptionHasRole, canAccessRoomAsync, roomAccessAttributes };
4 changes: 0 additions & 4 deletions apps/meteor/app/autotranslate/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,9 @@

import { TranslationProviderRegistry } from './autotranslate';
import './permissions';
import './methods/getSupportedLanguages';
import './methods/saveSettings';
import './methods/translateMessage';
import './googleTranslate';
import './deeplTranslate';
import './libreTranslate';
import './msTranslate';
import './methods/getProviderUiMetadata';

export { TranslationProviderRegistry };
2 changes: 0 additions & 2 deletions apps/meteor/app/channel-settings/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
import './methods/saveRoomSettings';

export { saveRoomTopic } from './functions/saveRoomTopic';
export { saveRoomName } from './functions/saveRoomName';
3 changes: 0 additions & 3 deletions apps/meteor/app/discussion/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import './permissions';

import './hooks/propagateDiscussionMetadata';

// Methods
import './methods/createDiscussion';
7 changes: 0 additions & 7 deletions apps/meteor/app/e2e/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,6 @@ import { api } from '@rocket.chat/core-services';
import { callbacks } from '../../../server/lib/callbacks';

import './beforeCreateRoom';
import './methods/setUserPublicAndPrivateKeys';
import './methods/getUsersOfRoomWithoutKey';
import './methods/updateGroupKey';
import './methods/setRoomKeyID';
import './methods/fetchMyKeys';
import './methods/resetOwnE2EKey';
import './methods/requestSubscriptionKeys';

callbacks.add(
'afterJoinRoom',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const { parseFileIntoMessageAttachments } = proxyquire.noCallThru().load('./send
'../../../../server/lib/callbacks': { callbacks: { runAsync: sinon.stub() } },
'../../../../server/lib/logger/system': { SystemLogger: { error: sinon.stub() } },
'../../../../server/lib/authorization/canAccessRoom': { canAccessRoomAsync: sinon.stub().resolves(true) },
'../../../lib/server/methods/sendMessage': { executeSendMessage: sinon.stub().resolves({}) },
'../../../../server/meteor-methods/messages/sendMessage': { executeSendMessage: sinon.stub().resolves({}) },
});

describe('sendFileMessage - Mass Assignment & Type Pollution Prevention', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import { getFileExtension } from '../../../../lib/utils/getFileExtension';
import { canAccessRoomAsync } from '../../../../server/lib/authorization/canAccessRoom';
import { callbacks } from '../../../../server/lib/callbacks';
import { SystemLogger } from '../../../../server/lib/logger/system';
import { executeSendMessage } from '../../../../server/meteor-methods/messages/sendMessage';
import { methodDeprecationLogger } from '../../../lib/server/lib/deprecationWarningLogger';
import { executeSendMessage } from '../../../lib/server/methods/sendMessage';
import { FileUpload } from '../lib/FileUpload';

function validateFileRequiredFields(file: Partial<IUpload>): asserts file is AtLeast<IUpload, '_id' | 'name' | 'type' | 'size'> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { removeEmpty } from '@rocket.chat/tools';
import limax from 'limax';

import { RecordConverter } from './RecordConverter';
import { createDirectMessage } from '../../../../../server/methods/createDirectMessage';
import { saveRoomSettings } from '../../../../channel-settings/server/methods/saveRoomSettings';
import { createDirectMessage } from '../../../../../server/meteor-methods/messages/createDirectMessage';
import { createChannelMethod } from '../../../../../server/meteor-methods/rooms/createChannel';
import { createPrivateGroupMethod } from '../../../../../server/meteor-methods/rooms/createPrivateGroup';
import { saveRoomSettings } from '../../../../../server/meteor-methods/rooms/saveRoomSettings';
import { notifyOnSubscriptionChangedByRoomId } from '../../../../lib/server/lib/notifyListener';
import { createChannelMethod } from '../../../../lib/server/methods/createChannel';
import { createPrivateGroupMethod } from '../../../../lib/server/methods/createPrivateGroup';
import type { IConversionCallbacks } from '../../definitions/IConversionCallbacks';

export class RoomConverter extends RecordConverter<IImportChannelRecord> {
Expand Down
Loading
Loading