Skip to content
This repository was archived by the owner on Nov 5, 2025. It is now read-only.
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
4 changes: 2 additions & 2 deletions src/definition/accessors/IRoomRead.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IMessage } from '../messages/index';
import type { IMessageRaw } from '../messages/index';
import type { IRoom } from '../rooms/index';
import type { IUser } from '../users/index';

Expand Down Expand Up @@ -56,7 +56,7 @@ export interface IRoomRead {
skip: number;
sort: Record<string, 1 | -1>;
}>,
): Promise<IMessage[]>;
): Promise<IMessageRaw[]>;

/**
* Gets an iterator for all of the users in the provided room.
Expand Down
40 changes: 40 additions & 0 deletions src/definition/messages/IMessageRaw.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { IBlock, Block } from '@rocket.chat/ui-kit';

import type { IRoom } from '../rooms';
import type { IUserLookup } from '../users';
import type { IMessageAttachment } from './IMessageAttachment';
import type { IMessageFile } from './IMessageFile';
import type { IMessageReactions } from './IMessageReaction';

/**
* The raw version of a message, without resolved information for relationship fields, i.e.
* `room`, `sender` and `editor` are not the complete entity like they are in `IMessage`
*
* This is used in methods that fetch multiple messages at the same time, as resolving the relationship
* fields require additional queries to the database and would hit the system's performance significantly.
*/
export interface IMessageRaw {
Comment thread
d-gubert marked this conversation as resolved.
id: string;
roomId: IRoom['id'];
sender: IUserLookup;
createdAt: Date;
threadId?: string;
text?: string;
updatedAt?: Date;
editor?: IUserLookup;
editedAt?: Date;
emoji?: string;
avatarUrl?: string;
alias?: string;
file?: IMessageFile;
attachments?: Array<IMessageAttachment>;
reactions?: IMessageReactions;
groupable?: boolean;
parseUrls?: boolean;
customFields?: { [key: string]: any };
blocks?: Array<IBlock | Block>;
starred?: Array<{ _id: string }>;
pinned?: boolean;
pinnedAt?: Date;
pinnedBy?: IUserLookup;
}
2 changes: 2 additions & 0 deletions src/definition/messages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { IMessageDeleteContext } from './IMessageDeleteContext';
import { IMessageFile } from './IMessageFile';
import { IMessageFollowContext } from './IMessageFollowContext';
import { IMessagePinContext } from './IMessagePinContext';
import { IMessageRaw } from './IMessageRaw';
import { IMessageReaction, IMessageReactions } from './IMessageReaction';
import { IMessageReactionContext } from './IMessageReactionContext';
import { IMessageReportContext } from './IMessageReportContext';
Expand Down Expand Up @@ -39,6 +40,7 @@ export {
IMessageAttachmentField,
IMessageAction,
IMessageFile,
IMessageRaw,
IMessageReactions,
IMessageReaction,
IPostMessageDeleted,
Expand Down
1 change: 1 addition & 0 deletions src/definition/users/IUserLookup.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface IUserLookup {
_id: string;
username: string;
name?: string;
}
4 changes: 2 additions & 2 deletions src/server/accessors/RoomRead.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { IRoomRead } from '../../definition/accessors';
import type { IMessage } from '../../definition/messages';
import type { IMessageRaw } from '../../definition/messages';
import type { IRoom } from '../../definition/rooms';
import type { IUser } from '../../definition/users';
import type { RoomBridge } from '../bridges';
Expand Down Expand Up @@ -30,7 +30,7 @@ export class RoomRead implements IRoomRead {
skip: number;
sort: Record<string, 1 | -1>;
}>,
): Promise<IMessage[]> {
): Promise<IMessageRaw[]> {
return this.roomBridge.doGetMessages(roomId, { limit: 100, ...options }, this.appId);
}

Expand Down
6 changes: 3 additions & 3 deletions src/server/bridges/RoomBridge.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IMessage } from '../../definition/messages';
import type { IMessage, IMessageRaw } from '../../definition/messages';
import type { IRoom } from '../../definition/rooms';
import type { IUser } from '../../definition/users';
import { PermissionDeniedError } from '../errors/PermissionDeniedError';
Expand Down Expand Up @@ -99,7 +99,7 @@ export abstract class RoomBridge extends BaseBridge {
sort?: Record<string, 1 | -1>;
},
appId: string,
): Promise<IMessage[]> {
): Promise<IMessageRaw[]> {
if (this.hasReadPermission(appId)) {
return this.getMessages(roomId, options, appId);
}
Expand Down Expand Up @@ -145,7 +145,7 @@ export abstract class RoomBridge extends BaseBridge {
sort?: Record<string, 1 | -1>;
},
appId: string,
): Promise<IMessage[]>;
): Promise<IMessageRaw[]>;

private hasWritePermission(appId: string): boolean {
if (AppPermissionManager.hasPermission(appId, AppPermissions.room.write)) {
Expand Down
8 changes: 4 additions & 4 deletions tests/server/accessors/RoomRead.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ import type { IUser } from '../../../src/definition/users';
import { RoomRead } from '../../../src/server/accessors';
import type { RoomBridge } from '../../../src/server/bridges';
import { TestData } from '../../test-data/utilities';
import type { IMessage } from '../../../src/definition/messages';
import type { IMessageRaw } from '../../../src/definition/messages';

export class RoomReadAccessorTestFixture {
private room: IRoom;

private user: IUser;

private messages: IMessage[];
private messages: IMessageRaw[];

private mockRoomBridgeWithRoom: RoomBridge;

@SetupFixture
public setupFixture() {
this.room = TestData.getRoom();
this.user = TestData.getUser();
this.messages = ['507f1f77bcf86cd799439011', '507f191e810c19729de860ea'].map((id) => TestData.getMessage(id));
this.messages = ['507f1f77bcf86cd799439011', '507f191e810c19729de860ea'].map((id) => TestData.getMessageRaw(id));

const theRoom = this.room;
const theUser = this.user;
Expand All @@ -44,7 +44,7 @@ export class RoomReadAccessorTestFixture {
doGetMembers(name, appId): Promise<Array<IUser>> {
return Promise.resolve([theUser]);
},
doGetMessages(roomId, appId, options): Promise<IMessage[]> {
doGetMessages(roomId, appId, options): Promise<IMessageRaw[]> {
return Promise.resolve(theMessages);
},
} as RoomBridge;
Expand Down
4 changes: 2 additions & 2 deletions tests/test-data/bridges/roomBridge.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IMessage } from '../../../src/definition/messages';
import type { IMessage, IMessageRaw } from '../../../src/definition/messages';
import type { IRoom } from '../../../src/definition/rooms';
import type { IUser } from '../../../src/definition/users';
import { RoomBridge } from '../../../src/server/bridges';
Expand Down Expand Up @@ -32,7 +32,7 @@ export class TestsRoomBridge extends RoomBridge {
throw new Error('Method not implemented.');
}

public getMessages(roomId: string, options: { limit: number; skip?: number; sort?: Record<string, 1 | -1> }, appId: string): Promise<IMessage[]> {
public getMessages(roomId: string, options: { limit: number; skip?: number; sort?: Record<string, 1 | -1> }, appId: string): Promise<IMessageRaw[]> {
throw new Error('Method not implemented.');
}

Expand Down
106 changes: 70 additions & 36 deletions tests/test-data/utilities.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { IHttp, IModify, IPersistence, IRead } from '../../src/definition/accessors';
import { HttpStatusCode } from '../../src/definition/accessors';
import type { IMessage } from '../../src/definition/messages';
import type { IMessage, IMessageAttachment, IMessageRaw } from '../../src/definition/messages';
import type { IRoom } from '../../src/definition/rooms';
import { RoomType } from '../../src/definition/rooms';
import type { ISetting } from '../../src/definition/settings';
Expand Down Expand Up @@ -61,6 +61,39 @@ export class TestInfastructureSetup {
}

const date = new Date();

const DEFAULT_ATTACHMENT = {
color: '#00b2b2',
collapsed: false,
text: 'Just an attachment that is used for testing',
timestampLink: 'https://google.com/',
thumbnailUrl: 'https://avatars0.githubusercontent.com/u/850391?s=88&v=4',
author: {
name: 'Author Name',
link: 'https://github.com/graywolf336',
icon: 'https://avatars0.githubusercontent.com/u/850391?s=88&v=4',
},
title: {
value: 'Attachment Title',
link: 'https://github.com/RocketChat',
displayDownloadLink: false,
},
imageUrl: 'https://rocket.chat/images/default/logo.svg',
audioUrl: 'http://www.w3schools.com/tags/horse.mp3',
videoUrl: 'http://www.w3schools.com/tags/movie.mp4',
fields: [
{
short: true,
title: 'Test',
value: 'Testing out something or other',
},
{
short: true,
title: 'Another Test',
value: '[Link](https://google.com/) something and this and that.',
},
],
};
export class TestData {
public static getDate(): Date {
return date;
Expand Down Expand Up @@ -126,41 +159,42 @@ export class TestData {
emoji: ':see_no_evil:',
avatarUrl: 'https://avatars0.githubusercontent.com/u/850391?s=88&v=4',
alias: 'Testing Bot',
attachments: [
{
collapsed: false,
color: '#00b2b2',
text: 'Just an attachment that is used for testing',
timestamp: new Date(),
timestampLink: 'https://google.com/',
thumbnailUrl: 'https://avatars0.githubusercontent.com/u/850391?s=88&v=4',
author: {
name: 'Author Name',
link: 'https://github.com/graywolf336',
icon: 'https://avatars0.githubusercontent.com/u/850391?s=88&v=4',
},
title: {
value: 'Attachment Title',
link: 'https://github.com/RocketChat',
displayDownloadLink: false,
},
imageUrl: 'https://rocket.chat/images/default/logo.svg',
audioUrl: 'http://www.w3schools.com/tags/horse.mp3',
videoUrl: 'http://www.w3schools.com/tags/movie.mp4',
fields: [
{
short: true,
title: 'Test',
value: 'Testing out something or other',
},
{
short: true,
title: 'Another Test',
value: '[Link](https://google.com/) something and this and that.',
},
],
},
],
attachments: [this.createAttachment()],
};
}

public static getMessageRaw(id?: string, text?: string): IMessageRaw {
const editorUser = TestData.getUser();
const senderUser = TestData.getUser();

return {
id: id || '4bShvoOXqB',
roomId: TestData.getRoom().id,
sender: {
_id: senderUser.id,
username: senderUser.username,
name: senderUser?.name,
},
text: text || 'This is just a test, do not be alarmed',
createdAt: date,
updatedAt: new Date(),
editor: {
_id: editorUser.id,
username: editorUser.username,
},
editedAt: new Date(),
emoji: ':see_no_evil:',
avatarUrl: 'https://avatars0.githubusercontent.com/u/850391?s=88&v=4',
alias: 'Testing Bot',
attachments: [this.createAttachment()],
};
}

private static createAttachment(attachment?: IMessageAttachment): IMessageAttachment {
attachment = attachment || DEFAULT_ATTACHMENT;
return {
timestamp: new Date(),
...attachment,
};
}

Expand Down