Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
91d4299
creates federation-service app
ricardogarim Jul 1, 2025
153551c
creates federation-matrix package
ricardogarim Jul 1, 2025
c2835af
creates monolith API for federation
ricardogarim Jul 1, 2025
5efcc8f
adds federation service settings
ricardogarim Jul 1, 2025
c1477f8
adds create federated room support
ricardogarim Jul 1, 2025
0381af9
chore: new federation callbacks listeners (#36421)
Jul 15, 2025
bf7f9d9
send message
ggazzo Sep 17, 2025
2125c0d
feat: basic support for accept invitation from remote
Jul 1, 2025
2610650
x
ricardogarim Jul 3, 2025
6b576a4
refactor: use self contained DI package from federation-sdk (#36379)
ggazzo Jul 7, 2025
f85ef27
chore: add federation routes to RC (monolith + service) (#36384)
Jul 9, 2025
5c14cb7
fix: avoid to register routes every time the fn gets called (#36411)
Jul 15, 2025
f4ed218
fix: provide the correct emitter instance
Jul 16, 2025
a452883
feat: adds license validation to federation packages and services (#3…
ricardogarim Jul 21, 2025
cc3abd9
chore: federation messages using new state resolution (#36548)
ricardogarim Jul 28, 2025
63d092d
refactor: provide env vars to federation sdk instead of loading them …
Jul 29, 2025
e7fee34
chore: support for the server key via settings (#36551)
Jul 31, 2025
1b579cd
feat: federation message reactions (#36420)
ggazzo Sep 17, 2025
633c710
feat: support for inviting users using the add members tab (#36447)
ggazzo Sep 17, 2025
dd6cb6d
feat: adds federation kick and leave support (#36572)
ricardogarim Aug 3, 2025
e92b60f
chore: remove unused var (fix lint)
Aug 4, 2025
fca6d7f
feat: support for redact message from RC to external (#36492)
Aug 4, 2025
bde5605
feat: federation edus (typing, presence) support (#36626)
Aug 5, 2025
43abc5d
feat: federation threads messaging (#36624)
ricardogarim Aug 5, 2025
535a4a0
fix: messages redaction echo (#36633)
ricardogarim Aug 6, 2025
f0c5212
feat: edit message (#36619)
Aug 6, 2025
07644c9
fix: use the same username pattern for federated users (#36641)
Aug 6, 2025
a229c76
feat: support for mentions and quotes on federation (#36669)
Aug 12, 2025
44171f2
feat: name and topic change (#36700)
debdutdeb Aug 13, 2025
473903f
feat: auto join rooms on invite (#36729)
ggazzo Sep 17, 2025
bcf3e12
feat: change room roles (#36730)
debdutdeb Aug 18, 2025
a0b52ab
getting it to build with homeserver code, too noisy to squashing
ggazzo Sep 17, 2025
d3f8559
fix: ui issue and simplify config passing to homeserver (#36761)
debdutdeb Aug 21, 2025
a05b6a2
cache homeserver repo correctly
debdutdeb Aug 21, 2025
222f01c
fix typecheck
sampaiodiego Aug 21, 2025
6da5f2d
refactor(federation-matrix): remove the need of `getMatrixLocalDomain…
sampaiodiego Sep 1, 2025
35e5f55
chore: await createFederationContainer for proper async handling
ggazzo Sep 3, 2025
c67bff0
fix: use new transaction entrypoint
sampaiodiego Sep 3, 2025
6d82d92
refactor: sets media configs on FederationMatrix init (#36862)
ricardogarim Sep 3, 2025
14285f3
feat: use native federation event queue (#36922)
sampaiodiego Sep 11, 2025
f2f7cd2
feat: adds Federation GET /events/{eventId} endpoint (#36873)
ricardogarim Sep 12, 2025
b7c35e3
feat: adds get state and state_id endpoints (#36929)
ggazzo Sep 15, 2025
2deb74f
feat: DMs (#36762)
MarcosSpessatto Sep 16, 2025
d2198bb
chore: refactor federation to use eventID branded types (#36954)
ggazzo Sep 16, 2025
27df54a
refactor(callbacks): update add method to return a cleanup function
ggazzo Sep 18, 2025
3c0064b
feat: introduce branded types for IRoomFederated and improve type safety
ggazzo Sep 18, 2025
9619660
chore: change afterRoomTopicChange signature
ggazzo Sep 18, 2025
98ef850
beforeChangeRoomRole signrature
ggazzo Sep 18, 2025
48d1d0e
refactor(addUserToRoom): change inviter type
ggazzo Sep 19, 2025
1a3fb7c
REVIEW `setupTypingEventListenerForRoom`
ggazzo Sep 19, 2025
ded34bc
feat: add license middleware for federation support
ggazzo Sep 19, 2025
0d89d11
feat: add middleware to check if federation is enabled
ggazzo Sep 19, 2025
604921c
refactor(reactions): callback signatures to include room parameter
ggazzo Sep 19, 2025
e6cc948
refactor(federation): streamline room federation checks and enhance t…
ggazzo Sep 19, 2025
8e192e6
feat(federation): integrate middleware for federation and license che…
ggazzo Sep 19, 2025
eb51988
fix: add optional params to /query/profile (#36956)
sampaiodiego Sep 19, 2025
65717c6
feat: adds federation event ACL (#36913)
ricardogarim Sep 19, 2025
e5d5cb5
feat(federation): add federation versioning to user and room models
ggazzo Sep 19, 2025
c30521d
fix: user federation version field
ggazzo Sep 19, 2025
ad201fa
refactor: set tshow to true for the first thread message in federated…
ricardogarim Sep 19, 2025
caf9a24
feat: add Federation allow list (#37010)
sampaiodiego Sep 19, 2025
29af986
fix: dm check on invite (#37012)
debdutdeb Sep 19, 2025
f3730c3
chore: publish federation fields for room
ggazzo Sep 20, 2025
23898d1
feat: adds federation files support (#36842)
ricardogarim Sep 20, 2025
075ef61
fix: loop caused by service federation adding users to room
ggazzo Sep 22, 2025
9ad3ba9
fix(federation): add missing federation fields (#37015)
ggazzo Sep 22, 2025
ef76e88
chore: organize federation settings (#36991)
rodrigok Sep 22, 2025
1606314
Fix unneeded federation version control
rodrigok Sep 21, 2025
c5ae119
chore(federation): refactor edu handling (#37013)
ggazzo Sep 22, 2025
6703c21
fix(federation): empty thread id leads to wrong reply (#37023)
ggazzo Sep 22, 2025
06a16ae
Fix isFederationEnabledMiddleware inverted logic
rodrigok Sep 21, 2025
eb0f19f
Fix typecast of processInvite
rodrigok Sep 21, 2025
0382d47
feat: add origin to room name to prevent cross-server conflicts (#37034)
ricardogarim Sep 23, 2025
9f75559
chore: remove matrix bridged collections (#37035)
sampaiodiego Sep 23, 2025
ebf0659
fix: fixes reviews of chore/federation-backup (#37016)
rodrigok Sep 23, 2025
26cfc6e
chore(federation): add setting to control EDUs (#37036)
rodrigok Sep 23, 2025
d546baf
fix: DM naming
sampaiodiego Sep 23, 2025
794f4b4
fix direct message rc -> synapse
ggazzo Sep 23, 2025
e2c6484
chore(federation): bring back domain setting (#37033)
rodrigok Sep 23, 2025
5b1c09e
chore(federation): generate signing key at first startup (#37039)
rodrigok Sep 23, 2025
3a25abb
fix(federation): DM first message not working (#37048)
rodrigok Sep 24, 2025
12c0113
chore: Use published federation package (#37046)
sampaiodiego Sep 24, 2025
5e1a275
fix(reaction): ensure beforeReacted is awaited in setReaction function
ggazzo Sep 24, 2025
8637212
chore(federation): increase time to accept DMs (#37054)
rodrigok Sep 24, 2025
ae7b86a
chore: upgrade federation zod
sampaiodiego Sep 24, 2025
0a0325e
chore: bump federation-sdk
sampaiodiego Sep 24, 2025
c45a6d4
fix: create federated user on DMs from RC > remote flow (#37043)
ricardogarim Sep 24, 2025
62ea375
bump: update federation-sdk to version 0.1.6
sampaiodiego Sep 24, 2025
712630f
chore: add @datastructures-js/heap and @datastructures-js/priority-qu…
ggazzo Sep 25, 2025
3bb316b
bump: federation-sdk
sampaiodiego Sep 25, 2025
a20cc72
chore: remover emoji converter file
sampaiodiego Sep 25, 2025
5896129
add last missing dep
sampaiodiego Sep 25, 2025
37c5bf7
align dep version
sampaiodiego Sep 25, 2025
1a32eb4
fix(federation): uploads not working properly (#37064)
rodrigok Sep 25, 2025
41768c5
feat(federation): accept remote join at 3rd party (#37072)
rodrigok Sep 25, 2025
6370679
fix: non authorized endpoints requiring authorization
sampaiodiego Sep 25, 2025
b96cff4
bump: @rocket.chat/federation-sdk
sampaiodiego Sep 25, 2025
51acb08
fix sending thumbs
sampaiodiego Sep 25, 2025
47f9d7e
fix lint
sampaiodiego Sep 25, 2025
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 .github/workflows/ci-test-storybook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ jobs:
runs-on: ubuntu-24.04

name: Test Storybook

steps:
- uses: actions/checkout@v4

- name: Setup NodeJS
uses: ./.github/actions/setup-node
with:
Expand Down Expand Up @@ -54,4 +55,3 @@ jobs:
flags: unit
verbose: true
token: ${{ secrets.CODECOV_TOKEN }}

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,5 @@ registration.yaml

storybook-static
development/tempo-data/

.env
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,6 @@ export async function saveRoomName(
await Message.saveSystemMessage('r', rid, displayName, user);
}

await callbacks.run('afterRoomNameChange', { room, name: displayName, oldName: room.name, userId: user._id });
await callbacks.run('afterRoomNameChange', { room, name: displayName, oldName: room.name, user });
return displayName;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { Meteor } from 'meteor/meteor';

import { callbacks } from '../../../../lib/callbacks';

export const saveRoomTopic = async function (
export const saveRoomTopic = async (
rid: string,
roomTopic: string | undefined,
user: {
username: string;
_id: string;
},
sendMessage = true,
) {
) => {
if (!Match.test(rid, String)) {
throw new Meteor.Error('invalid-room', 'Invalid room', {
function: 'RocketChat.saveRoomTopic',
Expand All @@ -28,6 +28,6 @@ export const saveRoomTopic = async function (
if (update && sendMessage) {
await Message.saveSystemMessage('room_changed_topic', rid, roomTopic || '', user);
}
await callbacks.run('afterRoomTopicChange', { rid, topic: roomTopic });
await callbacks.run('afterRoomTopicChange', undefined, { room, topic: roomTopic, user });
return update;
};
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ callbacks.add(

callbacks.add(
'afterDeleteMessage',
async (message, { _id, prid }) => {
async (message, { room: { _id, prid } }) => {
if (prid) {
const room = await Rooms.findOneById(_id, {
projection: {
Expand Down
8 changes: 4 additions & 4 deletions apps/meteor/app/lib/server/functions/addUserToRoom.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Apps, AppEvents } from '@rocket.chat/apps';
import { AppsEngineException } from '@rocket.chat/apps-engine/definition/exceptions';
import { Message, Team } from '@rocket.chat/core-services';
import type { IUser } from '@rocket.chat/core-typings';
import { type IUser } from '@rocket.chat/core-typings';
import { Subscriptions, Users, Rooms } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';

Expand All @@ -19,7 +19,7 @@ import { notifyOnRoomChangedById, notifyOnSubscriptionChangedById } from '../lib
* Caution - It does not validates if the user has permission to join room
*/

export const addUserToRoom = async function (
export const addUserToRoom = async (
rid: string,
user: Pick<IUser, '_id' | 'username'> | string,
inviter?: Pick<IUser, '_id' | 'username'>,
Expand All @@ -32,7 +32,7 @@ export const addUserToRoom = async function (
skipAlertSound?: boolean;
createAsHidden?: boolean;
} = {},
): Promise<boolean | undefined> {
): Promise<boolean | undefined> => {
const now = new Date();
const room = await Rooms.findOneById(rid);

Expand All @@ -57,7 +57,7 @@ export const addUserToRoom = async function (
}

try {
await beforeAddUserToRoom.run({ user: userToBeAdded, inviter }, room);
await beforeAddUserToRoom.run({ user: userToBeAdded, inviter: (inviter && (await Users.findOneById(inviter._id))) || undefined }, room);
} catch (error) {
throw new Meteor.Error((error as any)?.message);
}
Expand Down
15 changes: 10 additions & 5 deletions apps/meteor/app/lib/server/functions/createDirectRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ const getName = (members: IUser[]): string => members.map(({ username }) => user

export async function createDirectRoom(
members: IUser[] | string[],
roomExtraData = {},
roomExtraData: Partial<IRoom> = {},
options: {
creator?: string;
subscriptionExtra?: ISubscriptionExtraData;
federatedRoomId?: string;
},
): Promise<ICreatedRoom> {
const maxUsers = settings.get<number>('DirectMesssage_maxUsers') || 1;
Expand All @@ -59,17 +60,17 @@ export async function createDirectRoom(
);
}

await callbacks.run('beforeCreateDirectRoom', members);

const membersUsernames: string[] = members
.map((member) => {
if (typeof member === 'string') {
return member.replace('@', '');
return member;
}
return member.username;
})
.filter(isTruthy);

await callbacks.run('beforeCreateDirectRoom', membersUsernames, roomExtraData);

const roomMembers: IUser[] = await Users.findUsersByUsernames(membersUsernames, {
projection: { _id: 1, name: 1, username: 1, settings: 1, customFields: 1 },
}).toArray();
Expand Down Expand Up @@ -179,7 +180,11 @@ export async function createDirectRoom(
if (isNewRoom) {
const insertedRoom = await Rooms.findOneById(rid);

await callbacks.run('afterCreateDirectRoom', insertedRoom, { members: roomMembers, creatorId: options?.creator });
await callbacks.run('afterCreateDirectRoom', insertedRoom, {
members: roomMembers,
creatorId: options?.creator,
mrid: options?.federatedRoomId,
});

void Apps.self?.triggerEvent(AppEvents.IPostRoomCreate, insertedRoom);
}
Expand Down
22 changes: 21 additions & 1 deletion apps/meteor/app/lib/server/functions/createRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ async function createUsersSubscriptions({

const membersCursor = Users.findUsersByUsernames(members);

// TODO: Check re new federation-service - should we add them here or keep on createRoom inside of homeserver?!
for await (const member of membersCursor) {
try {
await beforeAddUserToRoom.run({ user: member, inviter: owner }, room);
Expand Down Expand Up @@ -131,7 +132,25 @@ export const createRoom = async <T extends RoomType>(
rid: string;
}
> => {
const { teamId, ...extraData } = roomExtraData || ({} as IRoom);
const { teamId, ...optionalExtraData } = roomExtraData || ({} as IRoom);

const hasFederatedMembers = members.some((member) => {
if (typeof member === 'string') {
return member.includes(':') && member.includes('@');
}
return member.username?.includes(':') && member.username?.includes('@');
});

const extraData = {
...optionalExtraData,
...((hasFederatedMembers || optionalExtraData.federated) && {
federated: true,
federation: {
version: 1,
// TODO we should be able to provide all values from here, currently we update on callback afterCreateRoom
},
}),
};

await prepareCreateRoomCallback.run({
type,
Expand Down Expand Up @@ -265,6 +284,7 @@ export const createRoom = async <T extends RoomType>(
callbacks.runAsync('afterCreatePrivateGroup', owner, room);
}
callbacks.runAsync('afterCreateRoom', owner, room);

if (shouldBeHandledByFederation) {
callbacks.runAsync('federation.afterCreateFederatedRoom', room, { owner, originalMemberList: members, options });
}
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/lib/server/functions/deleteMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export async function deleteMessage(message: IMessage, user: IUser): Promise<voi
await Rooms.decreaseMessageCountById(message.rid, 1);
}

await callbacks.run('afterDeleteMessage', deletedMsg, room);
await callbacks.run('afterDeleteMessage', deletedMsg, { room, user });

void notifyOnRoomChangedById(message.rid);

Expand Down
19 changes: 1 addition & 18 deletions apps/meteor/app/lib/server/functions/setUserActiveStatus.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Federation, FederationEE, License } from '@rocket.chat/core-services';
import type { IUser, IUserEmail } from '@rocket.chat/core-typings';
import { isUserFederated, isDirectMessageRoom } from '@rocket.chat/core-typings';
import { Rooms, Users, Subscriptions, MatrixBridgedUser } from '@rocket.chat/models';
import { Rooms, Users, Subscriptions } from '@rocket.chat/models';
import { Accounts } from 'meteor/accounts-base';
import { check } from 'meteor/check';
import { Meteor } from 'meteor/meteor';
Expand Down Expand Up @@ -71,22 +70,6 @@ export async function setUserActiveStatus(
});
}

if (user.active !== active) {
const remoteUser = await MatrixBridgedUser.getExternalUserIdByLocalUserId(userId);

if (remoteUser) {
if (active) {
throw new Meteor.Error('error-not-allowed', 'Deactivated federated users can not be re-activated', {
method: 'setUserActiveStatus',
});
}

const federation = (await License.hasValidLicense()) ? FederationEE : Federation;

await federation.deactivateRemoteUser(remoteUser);
}
}

// Users without username can't do anything, so there is no need to check for owned rooms
if (user.username != null && !active) {
const userAdmin = await Users.findOneAdmin(userId || '');
Expand Down
8 changes: 1 addition & 7 deletions apps/meteor/app/lib/server/methods/sendMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,7 @@ export async function executeSendMessage(uid: IUser['_id'], message: AtLeast<IMe
}
}

const user = await Users.findOneById(uid, {
projection: {
username: 1,
type: 1,
name: 1,
},
});
const user = await Users.findOneById(uid);
if (!user?.username) {
throw new Meteor.Error('error-invalid-user', 'Invalid user');
}
Expand Down
16 changes: 4 additions & 12 deletions apps/meteor/app/reactions/server/setReaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,7 @@ export const removeUserReaction = (message: IMessage, reaction: string, username
return message;
};

export async function setReaction(
room: Pick<IRoom, '_id' | 'muted' | 'unmuted' | 'reactWhenReadOnly' | 'ro' | 'lastMessage' | 'federated'>,
user: IUser,
message: IMessage,
reaction: string,
userAlreadyReacted?: boolean,
) {
export async function setReaction(room: IRoom, user: IUser, message: IMessage, reaction: string, userAlreadyReacted?: boolean) {
await Message.beforeReacted(message, room);

if (Array.isArray(room.muted) && room.muted.includes(user.username as string)) {
Expand Down Expand Up @@ -71,7 +65,7 @@ export async function setReaction(
await Rooms.setReactionsInLastMessage(room._id, message.reactions);
}
}
void callbacks.run('afterUnsetReaction', message, { user, reaction, shouldReact: false, oldMessage });
void callbacks.run('afterUnsetReaction', message, { user, reaction, shouldReact: false, oldMessage, room });

isReacted = false;
} else {
Expand All @@ -89,7 +83,7 @@ export async function setReaction(
await Rooms.setReactionsInLastMessage(room._id, message.reactions);
}

void callbacks.run('afterSetReaction', message, { user, reaction, shouldReact: true });
void callbacks.run('afterSetReaction', message, { user, reaction, shouldReact: true, room });

isReacted = true;
}
Expand Down Expand Up @@ -139,9 +133,7 @@ export async function executeSetReaction(
return;
}

const room = await Rooms.findOneById<
Pick<IRoom, '_id' | 'ro' | 'muted' | 'reactWhenReadOnly' | 'lastMessage' | 't' | 'prid' | 'federated'>
>(message.rid, { projection: { _id: 1, ro: 1, muted: 1, reactWhenReadOnly: 1, lastMessage: 1, t: 1, prid: 1, federated: 1 } });
const room = await Rooms.findOneById(message.rid);
if (!room) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'setReaction' });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ describe('useReloadOnError', () => {
);

// Mock fetch to return first, then second
(global.fetch as jest.Mock) = jest.fn().mockResolvedValueOnce(firstReply).mockResolvedValueOnce(secondReply);
(global.fetch as unknown as jest.Mock) = jest.fn().mockResolvedValueOnce(firstReply).mockResolvedValueOnce(secondReply);

const { result } = renderHook(() => useReloadOnError('/sampleurl?token=old', 'audio'));
const media = makeMediaEl();
Expand Down Expand Up @@ -217,7 +217,7 @@ describe('useReloadOnError', () => {

it('ignores initial play when expiry is unknown', async () => {
// no fetch expected on first play because expiresAt is not known yet
global.fetch = jest.fn();
(global.fetch as unknown as jest.Mock) = jest.fn();

const { result } = renderHook(() => useReloadOnError('/foo', 'audio'));
const media = makeMediaEl();
Expand Down
6 changes: 4 additions & 2 deletions apps/meteor/client/hooks/useIsFederationEnabled.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { useSetting } from '@rocket.chat/ui-contexts';

export const useIsFederationEnabled = () => {
const federationMatrixEnabled = useSetting('Federation_Matrix_enabled', false) === true;
return federationMatrixEnabled;
const matrixFederationEnabled = useSetting('Federation_Matrix_enabled', false);
const serviceFederationEnabled = useSetting('Federation_Service_Enabled', false);
const federationEnabled = matrixFederationEnabled || serviceFederationEnabled;
return federationEnabled;
};
13 changes: 6 additions & 7 deletions apps/meteor/client/lib/e2ee/rocketchat.e2e.room.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Base64 } from '@rocket.chat/base64';
import type { IE2EEMessage, IMessage, IRoom, ISubscription, IUser, IUploadWithUser, AtLeast } from '@rocket.chat/core-typings';
import type { IE2EEMessage, IMessage, IRoom, ISubscription, IUser, AtLeast, EncryptedMessageContent } from '@rocket.chat/core-typings';
import { isEncryptedMessageContent } from '@rocket.chat/core-typings';
import { Emitter } from '@rocket.chat/emitter';
import type { Optional } from '@tanstack/react-query';
import EJSON from 'ejson';
Expand Down Expand Up @@ -670,11 +671,9 @@ export class E2ERoom extends Emitter {
return this.encryptText(data);
}

async decryptContent<T extends IUploadWithUser | IE2EEMessage>(data: T) {
if (data.content && data.content.algorithm === 'rc.v1.aes-sha2') {
const content = await this.decrypt(data.content.ciphertext);
Object.assign(data, content);
}
async decryptContent<T extends EncryptedMessageContent>(data: T) {
const content = await this.decrypt(data.content.ciphertext);
Object.assign(data, content);

return data;
}
Expand All @@ -693,7 +692,7 @@ export class E2ERoom extends Emitter {
}
}

message = await this.decryptContent(message);
message = isEncryptedMessageContent(message) ? await this.decryptContent(message) : message;

return {
...message,
Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/client/lib/e2ee/rocketchat.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import QueryString from 'querystring';
import URL from 'url';

import type { IE2EEMessage, IMessage, IRoom, ISubscription, IUser, IUploadWithUser, MessageAttachment } from '@rocket.chat/core-typings';
import { isE2EEMessage } from '@rocket.chat/core-typings';
import { isE2EEMessage, isEncryptedMessageContent } from '@rocket.chat/core-typings';
import { Emitter } from '@rocket.chat/emitter';
import { imperativeModal } from '@rocket.chat/ui-client';
import EJSON from 'ejson';
Expand Down Expand Up @@ -664,7 +664,7 @@ class E2E extends Emitter {
}

async decryptFileContent(file: IUploadWithUser): Promise<IUploadWithUser> {
if (!file.rid) {
if (!file.rid || !isEncryptedMessageContent(file)) {
return file;
}

Expand Down
24 changes: 24 additions & 0 deletions apps/meteor/ee/server/api/federation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { IFederationMatrixService } from '@rocket.chat/core-services';
import { Logger } from '@rocket.chat/logger';
import type express from 'express';
import { WebApp } from 'meteor/webapp';

import { isRunningMs } from '../../../server/lib/isRunningMs';

const logger = new Logger('FederationRoutes');

export async function registerFederationRoutes(federationService: IFederationMatrixService): Promise<void> {
if (isRunningMs()) {
return;
}

try {
const routes = federationService.getAllRoutes();
(WebApp.rawConnectHandlers as unknown as ReturnType<typeof express>).use(routes.matrix.router).use(routes.wellKnown.router);

logger.log('[Federation] Registered federation routes');
} catch (error) {
logger.error('[Federation] Failed to register routes:', error);
throw error;
}
}
Loading
Loading