Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: remove Meteor calls for message history methods #34204

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
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
6 changes: 4 additions & 2 deletions apps/meteor/app/api/server/v1/channels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { saveRoomSettings } from '../../../channel-settings/server/methods/saveR
import { mountIntegrationQueryBasedOnPermissions } from '../../../integrations/server/lib/mountQueriesBasedOnPermission';
import { addUsersToRoomMethod } from '../../../lib/server/methods/addUsersToRoom';
import { createChannelMethod } from '../../../lib/server/methods/createChannel';
import { getChannelHistory } from '../../../lib/server/methods/getChannelHistory';
import { leaveRoomMethod } from '../../../lib/server/methods/leaveRoom';
import { settings } from '../../../settings/server';
import { normalizeMessagesForUser } from '../../../utils/server/lib/normalizeMessagesForUser';
Expand Down Expand Up @@ -162,10 +163,11 @@ API.v1.addRoute(

const { count = 20, offset = 0 } = await getPaginationItems(this.queryParams);

const result = await Meteor.callAsync('getChannelHistory', {
const result = await getChannelHistory({
rid: findResult._id,
fromUserId: this.userId,
latest: latest ? new Date(latest) : new Date(),
oldest: oldest && new Date(oldest),
oldest: oldest ? new Date(oldest) : undefined,
inclusive: inclusive === 'true',
offset,
count,
Expand Down
12 changes: 8 additions & 4 deletions apps/meteor/app/api/server/v1/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { escapeRegExp } from '@rocket.chat/string-helpers';
import { Meteor } from 'meteor/meteor';

import { reportMessage } from '../../../../server/lib/moderation/reportMessage';
import { getMessageHistory } from '../../../../server/publications/messages';
import { roomAccessAttributes } from '../../../authorization/server';
import { canAccessRoomAsync, canAccessRoomIdAsync } from '../../../authorization/server/functions/canAccessRoom';
import { canSendMessageAsync } from '../../../authorization/server/functions/canSendMessage';
Expand Down Expand Up @@ -100,17 +101,20 @@ API.v1.addRoute(
...(type && { type }),
};

const result = await Meteor.callAsync('messages/get', roomId, getMessagesQuery);
const result = await getMessageHistory(roomId, this.userId, getMessagesQuery);

if (!result) {
return API.v1.failure();
}
if (typeof result === 'boolean') {
return API.v1.success({ result: {} });
}
Comment on lines +109 to +111
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe instead of boolean, this one could return false so the check above can cover it and return failure instead? would that be a breaking change? would this one be a breaking change? 👀


return API.v1.success({
result: {
...(result.updated && { updated: await normalizeMessagesForUser(result.updated, this.userId) }),
...(result.deleted && { deleted: result.deleted }),
...(result.cursor && { cursor: result.cursor }),
updated: 'updated' in result ? await normalizeMessagesForUser(result.updated, this.userId) : [],
deleted: 'deleted' in result ? result.deleted : [],
cursor: 'cursor' in result ? result.cursor : undefined,
},
});
},
Expand Down
4 changes: 3 additions & 1 deletion apps/meteor/app/api/server/v1/groups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { hasAllPermissionAsync, hasPermissionAsync } from '../../../authorizatio
import { saveRoomSettings } from '../../../channel-settings/server/methods/saveRoomSettings';
import { mountIntegrationQueryBasedOnPermissions } from '../../../integrations/server/lib/mountQueriesBasedOnPermission';
import { createPrivateGroupMethod } from '../../../lib/server/methods/createPrivateGroup';
import { getChannelHistory } from '../../../lib/server/methods/getChannelHistory';
import { leaveRoomMethod } from '../../../lib/server/methods/leaveRoom';
import { normalizeMessagesForUser } from '../../../utils/server/lib/normalizeMessagesForUser';
import { API } from '../api';
Expand Down Expand Up @@ -504,8 +505,9 @@ API.v1.addRoute(

const showThreadMessages = this.queryParams.showThreadMessages !== 'false';

const result = await Meteor.callAsync('getChannelHistory', {
const result = await getChannelHistory({
rid: findResult.rid,
fromUserId: this.userId,
latest: latestDate,
oldest: oldestDate,
inclusive,
Expand Down
6 changes: 4 additions & 2 deletions apps/meteor/app/api/server/v1/im.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { canAccessRoomIdAsync } from '../../../authorization/server/functions/ca
import { hasAtLeastOnePermissionAsync, hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { saveRoomSettings } from '../../../channel-settings/server/methods/saveRoomSettings';
import { getRoomByNameOrIdWithOptionToJoin } from '../../../lib/server/functions/getRoomByNameOrIdWithOptionToJoin';
import { getChannelHistory } from '../../../lib/server/methods/getChannelHistory';
import { settings } from '../../../settings/server';
import { normalizeMessagesForUser } from '../../../utils/server/lib/normalizeMessagesForUser';
import { API } from '../api';
Expand Down Expand Up @@ -277,16 +278,17 @@ API.v1.addRoute(

const objectParams = {
rid: room._id,
fromUserId: this.userId,
latest: latest ? new Date(latest) : new Date(),
oldest: oldest && new Date(oldest),
oldest: oldest ? new Date(oldest) : undefined,
inclusive: inclusive === 'true',
offset,
count,
unreads: unreads === 'true',
showThreadMessages: showThreadMessages === 'true',
};

const result = await Meteor.callAsync('getChannelHistory', objectParams);
const result = await getChannelHistory(objectParams);

if (!result) {
return API.v1.unauthorized();
Expand Down
242 changes: 138 additions & 104 deletions apps/meteor/app/lib/server/methods/getChannelHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,125 +26,159 @@ declare module '@rocket.chat/ddp-client' {
}
}

Meteor.methods<ServerMethods>({
async getChannelHistory({ rid, latest, oldest, inclusive, offset = 0, count = 20, unreads, showThreadMessages = true }) {
check(rid, String);
export const getChannelHistory = async ({
rid,
fromUserId,
latest,
oldest,
inclusive,
offset = 0,
count = 20,
unreads,
showThreadMessages = true,
}: {
rid: string;
fromUserId: string;
latest?: Date;
oldest?: Date;
inclusive?: boolean;
offset?: number;
count?: number;
unreads?: boolean;
showThreadMessages?: boolean;
}): Promise<boolean | IMessage[] | { messages: IMessage[]; firstUnread?: any; unreadNotLoaded?: number }> => {
check(rid, String);

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

if (!Meteor.userId()) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getChannelHistory' });
}
if (!fromUserId) {
return false;
}

const fromUserId = Meteor.userId();
if (!fromUserId) {
return false;
}
const room = await Rooms.findOneById(rid);
if (!room) {
return false;
}

const room = await Rooms.findOneById(rid);
if (!room) {
return false;
}
if (!(await canAccessRoomAsync(room, { _id: fromUserId }))) {
return false;
}

if (!(await canAccessRoomAsync(room, { _id: fromUserId }))) {
return false;
}
// Make sure they can access the room
if (
room.t === 'c' &&
!(await hasPermissionAsync(fromUserId, 'preview-c-room')) &&
!(await Subscriptions.findOneByRoomIdAndUserId(rid, fromUserId, { projection: { _id: 1 } }))
) {
return false;
}

// Make sure they can access the room
if (
room.t === 'c' &&
!(await hasPermissionAsync(fromUserId, 'preview-c-room')) &&
!(await Subscriptions.findOneByRoomIdAndUserId(rid, fromUserId, { projection: { _id: 1 } }))
) {
return false;
}
// Ensure latest is always defined.
if (latest === undefined) {
latest = new Date();
}

// Ensure latest is always defined.
if (latest === undefined) {
latest = new Date();
}
// Verify oldest is a date if it exists

// Verify oldest is a date if it exists
if (oldest !== undefined && {}.toString.call(oldest) !== '[object Date]') {
throw new Meteor.Error('error-invalid-date', 'Invalid date', { method: 'getChannelHistory' });
}

if (oldest !== undefined && {}.toString.call(oldest) !== '[object Date]') {
throw new Meteor.Error('error-invalid-date', 'Invalid date', { method: 'getChannelHistory' });
const hiddenSystemMessages = settings.get<MessageTypesValues[]>('Hide_System_Messages');

const hiddenMessageTypes = getHiddenSystemMessages(room, hiddenSystemMessages);

const options: Record<string, unknown> = {
sort: {
ts: -1,
},
skip: offset,
limit: count,
};

const records =
oldest === undefined
? await Messages.findVisibleByRoomIdBeforeTimestampNotContainingTypes(
rid,
latest,
hiddenMessageTypes,
options,
showThreadMessages,
inclusive,
).toArray()
: await Messages.findVisibleByRoomIdBetweenTimestampsNotContainingTypes(
rid,
oldest,
latest,
hiddenMessageTypes,
options,
showThreadMessages,
inclusive,
).toArray();

const messages = await normalizeMessagesForUser(records, fromUserId);

if (unreads) {
let unreadNotLoaded = 0;
let firstUnread = undefined;

if (oldest !== undefined) {
const firstMsg = messages[messages.length - 1];
if (firstMsg !== undefined && firstMsg.ts > oldest) {
const unreadMessages = Messages.findVisibleByRoomIdBetweenTimestampsNotContainingTypes(
rid,
oldest,
firstMsg.ts,
hiddenMessageTypes,
{
limit: 1,
sort: {
ts: 1,
},
},
showThreadMessages,
);

const totalCursor = await Messages.countVisibleByRoomIdBetweenTimestampsNotContainingTypes(
rid,
oldest,
firstMsg.ts,
hiddenMessageTypes,
showThreadMessages,
);

firstUnread = (await unreadMessages.toArray())[0];
unreadNotLoaded = totalCursor;
}
}

const hiddenSystemMessages = settings.get<MessageTypesValues[]>('Hide_System_Messages');
return {
messages: messages || [],
firstUnread,
unreadNotLoaded,
};
}

const hiddenMessageTypes = getHiddenSystemMessages(room, hiddenSystemMessages);
return {
messages: messages || [],
};
};

const options: Record<string, unknown> = {
sort: {
ts: -1,
},
skip: offset,
limit: count,
};
Meteor.methods<ServerMethods>({
async getChannelHistory({ rid, latest, oldest, inclusive, offset = 0, count = 20, unreads, showThreadMessages = true }) {
check(rid, String);

const records =
oldest === undefined
? await Messages.findVisibleByRoomIdBeforeTimestampNotContainingTypes(
rid,
latest,
hiddenMessageTypes,
options,
showThreadMessages,
inclusive,
).toArray()
: await Messages.findVisibleByRoomIdBetweenTimestampsNotContainingTypes(
rid,
oldest,
latest,
hiddenMessageTypes,
options,
showThreadMessages,
inclusive,
).toArray();

const messages = await normalizeMessagesForUser(records, fromUserId);

if (unreads) {
let unreadNotLoaded = 0;
let firstUnread = undefined;

if (oldest !== undefined) {
const firstMsg = messages[messages.length - 1];
if (firstMsg !== undefined && firstMsg.ts > oldest) {
const unreadMessages = Messages.findVisibleByRoomIdBetweenTimestampsNotContainingTypes(
rid,
oldest,
firstMsg.ts,
hiddenMessageTypes,
{
limit: 1,
sort: {
ts: 1,
},
},
showThreadMessages,
);

const totalCursor = await Messages.countVisibleByRoomIdBetweenTimestampsNotContainingTypes(
rid,
oldest,
firstMsg.ts,
hiddenMessageTypes,
showThreadMessages,
);

firstUnread = (await unreadMessages.toArray())[0];
unreadNotLoaded = totalCursor;
}
}
if (!Meteor.userId()) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getChannelHistory' });
}

return {
messages: messages || [],
firstUnread,
unreadNotLoaded,
};
const fromUserId = Meteor.userId();
if (!fromUserId) {
return false;
}

return {
messages: messages || [],
};
return getChannelHistory({ rid, fromUserId, latest, oldest, inclusive, offset, count, unreads, showThreadMessages });
},
});
Loading
Loading