Skip to content
Draft
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
96 changes: 96 additions & 0 deletions .changeset/remove-orphan-ddp-methods.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
---
'@rocket.chat/meteor': major
---

**Breaking:** Removed 86 orphan Meteor (DDP) methods that no longer have callers inside the Rocket.Chat codebase. External DDP/SDK clients that still invoke these by name will receive a `Method 'X' not found [404]` error. Clients should migrate to the matching `/v1/...` REST endpoint where one exists, or stop using the method otherwise.

Removed methods:

- `OAuth.retrieveCredential`
- `UserPresence:setDefaultStatus`
- `addAllUserToRoom`
- `addIncomingIntegration` — use `POST /v1/integrations.create`
- `addOutgoingIntegration` — use `POST /v1/integrations.create`
- `addRoomLeader` — use `POST /v1/channels.addLeader` / `groups.addLeader`
- `addRoomModerator` — use `POST /v1/channels.addModerator` / `groups.addModerator`
- `addRoomOwner` — use `POST /v1/channels.addOwner` / `groups.addOwner`
- `addSamlService`
- `addUserToRoom` — use `POST /v1/channels.invite` / `groups.invite`
- `addWebdavAccountByToken`
- `archiveRoom` — use `POST /v1/channels.archive` / `groups.archive`
- `autoTranslate.saveSettings`
- `botRequest`
- `browseChannels` — use `GET /v1/directory`
- `channelsList` — use `GET /v1/channels.list`
- `cleanRoomHistory` — use `POST /v1/rooms.cleanHistory`
- `createChannel` — use `POST /v1/channels.create`
- `createDiscussion` — use `POST /v1/rooms.createDiscussion`
- `deleteCustomUserStatus` — use `POST /v1/custom-user-status.delete`
- `deleteEmojiCustom` — use `POST /v1/emoji-custom.delete`
- `deleteIncomingIntegration` — use `POST /v1/integrations.remove`
- `deleteOAuthApp` — use `POST /v1/oauth-apps.delete`
- `deleteOutgoingIntegration` — use `POST /v1/integrations.remove`
- `deleteUser` — use `POST /v1/users.delete`
- `deleteUserOwnAccount` — use `POST /v1/users.deleteOwnAccount`
- `downloadPublicImportFile` — use `POST /v1/downloadPublicImportFile`
- `e2e.fetchMyKeys` — use `GET /v1/e2e.fetchMyKeys`
- `e2e.setUserPublicAndPrivateKeys` — use `POST /v1/e2e.setUserPublicAndPrivateKeys`
- `followMessage` — use `POST /v1/chat.followMessage`
- `getChannelHistory` — use `GET /v1/channels.history`
- `getImportFileData` — use `GET /v1/getImportFileData`
- `getImportProgress` — use `GET /v1/getCurrentImportOperation`
- `getLatestImportOperations` — use `GET /v1/getLatestImportOperations`
- `getRoomIdByNameOrId`
- `getRoomJoinCode`
- `getRoomNameById` — use `GET /v1/rooms.info`
- `getS3FileUrl`
- `getStatistics` — use `GET /v1/statistics`
- `getThreadsList` — use `GET /v1/chat.getThreadsList`
- `getTotalChannels`
- `getUserMentionsByChannel` — use `GET /v1/channels.getAllUserMentionsByChannel`
- `getUserStatusText`
- `getUsernameSuggestion`
- `getUsersOfRoom` — use `GET /v1/channels.members` / `groups.members`
- `hideRoom` — use `POST /v1/rooms.leave`
- `ignoreUser` — use `GET /v1/chat.ignoreUser`
- `insertOrUpdateEmoji` — use `POST /v1/emoji-custom.create` / `update`
- `insertOrUpdateUserStatus`
- `joinDefaultChannels`
- `license:getTags`
- `license:hasLicense` — use `GET /v1/licenses.info`
- `messageSearch` — use `GET /v1/chat.search`
- `messages/get`
- `openRoom`
- `pinMessage` — use `POST /v1/chat.pinMessage`
- `raix:push-update`
- `readMessages` — use `POST /v1/subscriptions.read`
- `removeRoomLeader` — use `POST /v1/channels.removeLeader` / `groups.removeLeader`
- `removeRoomModerator` — use `POST /v1/channels.removeModerator` / `groups.removeModerator`
- `removeRoomOwner` — use `POST /v1/channels.removeOwner` / `groups.removeOwner`
- `removeUserFromRoom` — use `POST /v1/channels.kick` / `groups.kick`
- `resetAvatar` — use `POST /v1/users.resetAvatar`
- `rocketchatSearch.suggest`
- `saveAudioNotificationValue`
- `saveNotificationSettings` — use `POST /v1/rooms.saveNotification`
- `saveSetting` — use `POST /v1/settings/:_id`
- `saveUserPreferences` — use `POST /v1/users.setPreferences`
- `sendMessageLivechat`
- `sendSMTPTestEmail`
- `setEmail` — use `POST /v1/users.update`
- `setRealName` — use `POST /v1/users.update`
- `setUserActiveStatus` — use `POST /v1/users.setActiveStatus`
- `starMessage` — use `POST /v1/chat.starMessage`
- `startImport` — use `POST /v1/startImport`
- `toggleFavorite` — use `POST /v1/rooms.favorite`
- `unarchiveRoom` — use `POST /v1/channels.unarchive` / `groups.unarchive`
- `unfollowMessage` — use `POST /v1/chat.unfollowMessage`
- `unpinMessage` — use `POST /v1/chat.unPinMessage`
- `unreadMessages` — use `POST /v1/subscriptions.unread`
- `updateIncomingIntegration` — use `POST /v1/integrations.update`
- `updateMessage` — use `POST /v1/chat.update`
- `updateOAuthApp` — use `POST /v1/oauth-apps.update`
- `updateOutgoingIntegration` — use `POST /v1/integrations.update`
- `uploadEmojiCustom`
- `uploadImportFile` — use `POST /v1/uploadImportFile`

Methods that look orphan to the static audit but are still reachable indirectly (admin `MethodActionInput` dynamic dispatch, cloud admin actions, the `CachedStore` template-literal call, or `useMethod`/`sdk.call` with a conditional/template-literal name) stay registered. Those are listed under the skip list in `scripts/remove-orphan-ddp-methods.mjs`.
1 change: 0 additions & 1 deletion apps/meteor/app/autotranslate/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import { TranslationProviderRegistry } from './autotranslate';
import './permissions';
import './methods/getSupportedLanguages';
import './methods/saveSettings';
import './methods/translateMessage';
import './googleTranslate';
import './deeplTranslate';
Expand Down
26 changes: 0 additions & 26 deletions apps/meteor/app/autotranslate/server/methods/saveSettings.ts

This file was deleted.

19 changes: 0 additions & 19 deletions apps/meteor/app/bot-helpers/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import type { IUser } from '@rocket.chat/core-typings';
import { UserStatus } from '@rocket.chat/core-typings';
import type { ServerMethods } from '@rocket.chat/ddp-client';
import { Rooms, Users } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';
import type { Filter, FindCursor } from 'mongodb';

import { removeUserFromRoomMethod } from '../../../server/methods/removeUserFromRoom';
import { hasRoleAsync } from '../../authorization/server/functions/hasRole';
import { addUserToRole } from '../../authorization/server/methods/addUserToRole';
import { removeUserFromRole } from '../../authorization/server/methods/removeUserFromRole';
import { addUsersToRoomMethod } from '../../lib/server/methods/addUsersToRoom';
Expand Down Expand Up @@ -195,20 +193,3 @@ const botHelpers = new BotHelpers();
settings.watch<string>('BotHelpers_userFields', (value) => {
botHelpers.setupCursors(value);
});

declare module '@rocket.chat/ddp-client' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
botRequest: (prop: keyof BotHelpers, ...params: unknown[]) => Promise<unknown>;
}
}

Meteor.methods<ServerMethods>({
async botRequest(...args) {
const userID = Meteor.userId();
if (userID && (await hasRoleAsync(userID, 'bot'))) {
return botHelpers.request(...args, userID);
}
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'botRequest' });
},
});
41 changes: 0 additions & 41 deletions apps/meteor/app/discussion/server/methods/createDiscussion.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { Message } from '@rocket.chat/core-services';
import type { IMessage, IRoom, IUser, MessageAttachmentDefault } from '@rocket.chat/core-typings';
import type { ServerMethods } from '@rocket.chat/ddp-client';
import { Messages, Rooms, Users } from '@rocket.chat/models';
import { Random } from '@rocket.chat/random';
import { check, Match } from 'meteor/check';
import { Meteor } from 'meteor/meteor';

import { i18n } from '../../../../server/lib/i18n';
Expand All @@ -15,7 +13,6 @@ import { attachMessage } from '../../../lib/server/functions/attachMessage';
import { createRoom } from '../../../lib/server/functions/createRoom';
import { sendMessage } from '../../../lib/server/functions/sendMessage';
import { afterSaveMessageAsync } from '../../../lib/server/lib/afterSaveMessage';
import { methodDeprecationLogger } from '../../../lib/server/lib/deprecationWarningLogger';
import { settings } from '../../../settings/server';

const getParentRoom = async (rid: IRoom['_id']) => {
Expand Down Expand Up @@ -197,13 +194,6 @@ const create = async ({
return discussion;
};

declare module '@rocket.chat/ddp-client' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
createDiscussion: typeof create;
}
}

export const createDiscussion = async (
userId: string,
{ prid, pmid, t_name: discussionName, reply, users, encrypted, topic }: Omit<CreateDiscussionProperties, 'user'>,
Expand Down Expand Up @@ -235,34 +225,3 @@ export const createDiscussion = async (

return create({ prid, pmid, t_name: discussionName, reply, users, user, encrypted, topic });
};

Meteor.methods<ServerMethods>({
/**
* Create discussion by room or message
* @constructor
* @param {string} prid - Parent Room Id - The room id, optional if you send pmid.
* @param {string} pmid - Parent Message Id - Create the discussion by a message, optional.
* @param {string} reply - The reply, optional
* @param {string} t_name - discussion name
* @param {string[]} users - users to be added
* @param {boolean} encrypted - if the discussion's e2e encryption should be enabled.
*/
async createDiscussion({ prid, pmid, t_name: discussionName, reply, users, encrypted }: CreateDiscussionProperties) {
methodDeprecationLogger.method('createDiscussion', '9.0.0', '/v1/rooms.createDiscussion');
check(prid, Match.Maybe(String));
check(pmid, Match.Maybe(String));
check(reply, Match.Maybe(String));
check(discussionName, String);
check(users, [String]);
check(encrypted, Match.Maybe(Boolean));

const uid = Meteor.userId();
if (!uid) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
method: 'DiscussionCreation',
});
}

return createDiscussion(uid, { prid, pmid, t_name: discussionName, reply, users, encrypted });
},
});
1 change: 0 additions & 1 deletion apps/meteor/app/e2e/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import './methods/setUserPublicAndPrivateKeys';
import './methods/getUsersOfRoomWithoutKey';
import './methods/updateGroupKey';
import './methods/setRoomKeyID';
import './methods/fetchMyKeys';
import './methods/resetOwnE2EKey';
import './methods/requestSubscriptionKeys';

Expand Down
23 changes: 0 additions & 23 deletions apps/meteor/app/e2e/server/methods/fetchMyKeys.ts

This file was deleted.

30 changes: 0 additions & 30 deletions apps/meteor/app/e2e/server/methods/setUserPublicAndPrivateKeys.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
import type { ServerMethods } from '@rocket.chat/ddp-client';
import { Rooms, Users } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';

import { methodDeprecationLogger } from '../../../lib/server/lib/deprecationWarningLogger';
import { notifyOnRoomChangedById } from '../../../lib/server/lib/notifyListener';

declare module '@rocket.chat/ddp-client' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
'e2e.setUserPublicAndPrivateKeys'({ public_key, private_key }: { public_key: string; private_key: string; force?: boolean }): void;
}
}

const isKeysResult = (result: any): result is { public_key: string; private_key: string } => {
return result.private_key && result.public_key;
};
Expand Down Expand Up @@ -40,24 +31,3 @@ export const setUserPublicAndPrivateKeysMethod = async (

void notifyOnRoomChangedById(subscribedRoomIds);
};

Meteor.methods<ServerMethods>({
async 'e2e.setUserPublicAndPrivateKeys'(keyPair) {
methodDeprecationLogger.method('e2e.setUserPublicAndPrivateKeys', '9.0.0', '/v1/e2e.setUserPublicAndPrivateKeys');
const userId = Meteor.userId();

if (!userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
method: 'e2e.setUserPublicAndPrivateKeys',
});
}

if (!keyPair.public_key || !keyPair.private_key) {
throw new Meteor.Error('error-invalid-keys', 'Invalid keys', {
method: 'e2e.setUserPublicAndPrivateKeys',
});
}

await setUserPublicAndPrivateKeysMethod(userId, keyPair);
},
});
2 changes: 0 additions & 2 deletions apps/meteor/app/emoji-custom/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
import './startup/emoji-custom';
import './methods/deleteEmojiCustom';
import './methods/insertOrUpdateEmoji';
import './methods/uploadEmojiCustom';
20 changes: 0 additions & 20 deletions apps/meteor/app/emoji-custom/server/methods/deleteEmojiCustom.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
import { api } from '@rocket.chat/core-services';
import type { ICustomEmojiDescriptor } from '@rocket.chat/core-typings';
import type { ServerMethods } from '@rocket.chat/ddp-client';
import { EmojiCustom } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';

import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { methodDeprecationLogger } from '../../../lib/server/lib/deprecationWarningLogger';
import { RocketChatFileEmojiCustomInstance } from '../startup/emoji-custom';

declare module '@rocket.chat/ddp-client' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
deleteEmojiCustom(emojiID: ICustomEmojiDescriptor['_id']): boolean;
}
}

export const deleteEmojiCustom = async (userId: string, emojiID: ICustomEmojiDescriptor['_id']): Promise<boolean> => {
if (!(await hasPermissionAsync(userId, 'manage-emoji'))) {
throw new Meteor.Error('not_authorized');
Expand All @@ -33,14 +24,3 @@ export const deleteEmojiCustom = async (userId: string, emojiID: ICustomEmojiDes

return true;
};

Meteor.methods<ServerMethods>({
async deleteEmojiCustom(emojiID) {
methodDeprecationLogger.method('deleteEmojiCustom', '9.0.0', '/v1/emoji-custom.delete');
if (!this.userId) {
throw new Meteor.Error('not_authorized');
}

return deleteEmojiCustom(this.userId, emojiID);
},
});
33 changes: 0 additions & 33 deletions apps/meteor/app/emoji-custom/server/methods/insertOrUpdateEmoji.ts

This file was deleted.

Loading
Loading