Skip to content
Closed
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
52 changes: 38 additions & 14 deletions apps/meteor/ee/server/startup/federation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,57 @@ import { FederationMatrix, setupFederationMatrix } from '@rocket.chat/federation
import { InstanceStatus } from '@rocket.chat/instance-status';
import { Logger } from '@rocket.chat/logger';

import { settings } from '../../../app/settings/server';
import { StreamerCentral } from '../../../server/modules/streamer/streamer.module';
import { registerFederationRoutes } from '../api/federation';

const logger = new Logger('Federation');

const CRITICAL_SETTINGS = [
'Federation_Service_Enabled',
'Federation_Service_Domain',
'Federation_Service_Matrix_Signing_Key',
'Federation_Service_Matrix_Signing_Algorithm',
'Federation_Service_Matrix_Signing_Version',
'Federation_Service_Join_Encrypted_Rooms',
'Federation_Service_Join_Non_Private_Rooms',
'Federation_Service_EDU_Process_Typing',
'Federation_Service_EDU_Process_Presence',
];

let serviceRegistered = false;
let watcherRegistered = false;

export const startFederationService = async (): Promise<void> => {
try {
const isEnabled = await setupFederationMatrix(InstanceStatus.id());
if (isEnabled) {
if (!serviceRegistered) {
api.registerService(new FederationMatrix());

api.registerService(new FederationMatrix());
await registerFederationRoutes();

await registerFederationRoutes();
// TODO move to service/setup?
StreamerCentral.on('broadcast', (name, eventName, args) => {
if (name === 'notify-room' && eventName.endsWith('user-activity')) {
const [rid] = eventName.split('/');
const [user, activity] = args;
void FederationMatrixService.notifyUserTyping(rid, user, activity.includes('user-typing'));
}
});

// only registers the typing listener if the service is enabled
if (!isEnabled) {
return;
serviceRegistered = true;
}
}

// TODO move to service/setup?
StreamerCentral.on('broadcast', (name, eventName, args) => {
if (name === 'notify-room' && eventName.endsWith('user-activity')) {
const [rid] = eventName.split('/');
const [user, activity] = args;
void FederationMatrixService.notifyUserTyping(rid, user, activity.includes('user-typing'));
}
});
if (!watcherRegistered) {
settings.watchMultiple(CRITICAL_SETTINGS, async () => {
await startFederationService();
});
watcherRegistered = true;
}
} catch (error) {
logger.error('Failed to start federation-matrix service:', error);
logger.error('Failed to start federation service', { error });
throw error;
}
};
48 changes: 29 additions & 19 deletions ee/packages/federation-matrix/src/setup.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { License } from '@rocket.chat/core-services';
import { Emitter } from '@rocket.chat/emitter';
import type { HomeserverEventSignatures } from '@rocket.chat/federation-sdk';
import { ConfigService, createFederationContainer } from '@rocket.chat/federation-sdk';
import { ConfigService, createFederationContainer, getAllServices } from '@rocket.chat/federation-sdk';
import { Logger } from '@rocket.chat/logger';
import { Settings } from '@rocket.chat/models';

import { registerEvents } from './events';

const logger = new Logger('FederationSetup');

let containerInitialized = false;

function validateDomain(domain: string): boolean {
const value = domain.trim();

Expand Down Expand Up @@ -40,6 +42,11 @@ export async function setupFederationMatrix(instanceId: string): Promise<boolean
const settingEnabled = (await Settings.getValueById<boolean>('Federation_Service_Enabled')) || false;
const serverName = (await Settings.getValueById<string>('Federation_Service_Domain')) || '';

const serviceEnabled = (await License.hasModule('federation')) && settingEnabled && validateDomain(serverName);
if (!serviceEnabled) {
return false;
}

const processEDUTyping = (await Settings.getValueById<boolean>('Federation_Service_EDU_Process_Typing')) || false;
const processEDUPresence = (await Settings.getValueById<boolean>('Federation_Service_EDU_Process_Presence')) || false;
const signingKey = (await Settings.getValueById<string>('Federation_Service_Matrix_Signing_Key')) || '';
Expand All @@ -52,7 +59,7 @@ export async function setupFederationMatrix(instanceId: string): Promise<boolean
const mongoUri = process.env.MONGO_URL || 'mongodb://localhost:3001/meteor';
const dbName = process.env.DATABASE_NAME || new URL(mongoUri).pathname.slice(1);

const config = new ConfigService({
const configValues = {
instanceId,
serverName,
keyRefreshInterval: Number.parseInt(process.env.MATRIX_KEY_REFRESH_INTERVAL || '60', 10),
Expand Down Expand Up @@ -89,26 +96,29 @@ export async function setupFederationMatrix(instanceId: string): Promise<boolean
allowedEncryptedRooms,
allowedNonPrivateRooms,
},
});
};

const eventHandler = new Emitter<HomeserverEventSignatures>();
if (!containerInitialized) {
const config = new ConfigService(configValues);
const eventHandler = new Emitter<HomeserverEventSignatures>();

await createFederationContainer(
{
emitter: eventHandler,
},
config,
);

const serviceEnabled = (await License.hasModule('federation')) && settingEnabled && validateDomain(serverName);
if (!serviceEnabled) {
return false;
await createFederationContainer(
{
emitter: eventHandler,
},
config,
);

registerEvents(eventHandler, serverName, {
typing: processEDUTyping,
presence: processEDUPresence,
});

containerInitialized = true;
} else {
const services = getAllServices();
services.config.updateConfig(configValues);
}
Comment on lines +118 to 121
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 24, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Fix TypeScript compilation error: updateConfig method does not exist.

The pipeline failure indicates that updateConfig is not a property of ConfigService. According to the PR description, this relies on homeserver PR #289 which implements the method.

Verify the following:

Additionally, check the package version of @rocket.chat/federation-sdk to ensure it includes the updateConfig method:

If the method doesn't exist yet, this PR should either:

  1. Wait for the SDK to be updated with the updateConfig method
  2. Update the SDK dependency version to include the new method
  3. Add a type assertion or type extension as a temporary workaround (not recommended)

🏁 Script executed:

#!/bin/bash
# Check if updateConfig method exists in ConfigService type definition
ast-grep --pattern $'class ConfigService {
  $$$
  updateConfig($$$) {
    $$$
  }
  $$$
}'

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Check the version of federation-sdk in package.json files
fd -e json -x cat {} | jq -r 'select(.dependencies["@rocket.chat/federation-sdk"] or .devDependencies["@rocket.chat/federation-sdk"]) | {file: input_filename, version: (.dependencies["@rocket.chat/federation-sdk"] // .devDependencies["@rocket.chat/federation-sdk"])}'

Length of output: 66


I need to take a different approach with simpler, more targeted searches. Let me verify the codebase more directly:


---

🏁 Script executed:

```shell
#!/bin/bash
# Search for ConfigService definition (could be class, interface, or type)
rg -nA5 "ConfigService\s*[=\{:]" --type ts --type tsx

Length of output: 27


🏁 Script executed:

#!/bin/bash
# Search for getAllServices function definition
rg -nA3 "function getAllServices\|const getAllServices" --type ts --type tsx

Length of output: 27


🏁 Script executed:

#!/bin/bash
# Look at the actual setup.ts file around the problematic lines
cat ee/packages/federation-matrix/src/setup.ts | head -130 | tail -30

Length of output: 568


🏁 Script executed:

#!/bin/bash
# Search for updateConfig method definition anywhere
rg -nB2 -A5 "updateConfig\s*\(" --type ts --type tsx

Length of output: 27


🏁 Script executed:

#!/bin/bash
# Simple check of federation-sdk version in main package.json
grep -A2 -B2 "federation-sdk" package.json

Length of output: 0


Let me fix the commands and retry with corrected search patterns:


---

🏁 Script executed:

```shell
#!/bin/bash
# Search for ConfigService definition with simpler pattern
rg -nA5 "class ConfigService|interface ConfigService|type ConfigService" --type ts

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Search for getAllServices function with simpler pattern
rg -nA3 "getAllServices" --type ts | head -50

Length of output: 3057


🏁 Script executed:

#!/bin/bash
# Check package.json in the federation-matrix directory
find ee/packages/federation-matrix -name "package.json" -exec grep -l "federation-sdk" {} \;

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Look for updateConfig definition
rg -nB2 -A5 "updateConfig" --type ts | head -100

Length of output: 1426


🏁 Script executed:

#!/bin/bash
# Check federation-matrix package.json for dependencies
cat ee/packages/federation-matrix/package.json | grep -A5 -B5 "dependencies\|federation"

Length of output: 642



---

🏁 Script executed:

```shell
#!/bin/bash
# Search for federation-sdk in node_modules or check if it's installed
find . -path "*/node_modules/@rocket.chat/federation-sdk*" -type d | head -5

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Search for federation-sdk source files or look for ConfigService type definitions
rg -l "federation-sdk" --type ts | grep -E "(node_modules|dist)" | head -10

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Check if there's a federation-sdk package source in the workspace
find ee/packages -name "federation-sdk*" -o -name "*federation*sdk*" | head -20

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Search for any type definitions or imports of ConfigService to understand its type
rg "ConfigService" --type ts -B2 -A2 | head -80

Length of output: 903



---

🌐 Web query:

```web
@rocket.chat/federation-sdk updateConfig method ConfigService

💡 Result:

Do you want the method signature, usage example, or the source code for ConfigService.updateConfig? I can look it up — shall I search the repo/npm docs now?



---

🌐 Web query:

```web
@rocket.chat/federation-sdk version 0.2.0 npm package

💡 Result:

I couldn't find a published @rocket.chat/federation-sdk version 0.2.0 on the public registries. The package appears to have 0.1.x releases (latest listed ~0.1.18); no 0.2.0 release is shown. See registry listings. [1][2]

If you intended to install the latest published release, use:
npm install @rocket.chat/federation-sdk@latest
(Replace @latest with a specific 0.1.x version if you need one.) [1][2]

Sources:
[1] Socket.dev package page for @rocket.chat/federation-sdk (versions list).
[2] Libraries.io npm listing for @rocket.chat/federation-sdk.


Dependency blocker: @rocket.chat/federation-sdk v0.2.0 does not exist yet.

The package appears to have 0.1.x releases; no 0.2.0 release is shown. The code at line 120 calls services.config.updateConfig(configValues), but this method does not exist in any publicly available version of the SDK. Since the PR description references an unreleased homeserver PR (#289) that implements updateConfig, this indicates v0.2.0 is still in development.

Action required:

  • Wait for @rocket.chat/federation-sdk v0.2.0 to be released with the updateConfig method, or
  • Update the version constraint in ee/packages/federation-matrix/package.json once the SDK is published
🧰 Tools
🪛 GitHub Actions: CI

[error] 120-120: TS2339: Property 'updateConfig' does not exist on type 'ConfigService'.

🤖 Prompt for AI Agents
In ee/packages/federation-matrix/src/setup.ts around lines 118 to 121, the code
calls services.config.updateConfig(configValues) which depends on
@rocket.chat/federation-sdk v0.2.0 that is not yet released; either remove or
guard this call until the SDK is published: replace the direct call with a
runtime check like if (typeof services.config.updateConfig === 'function')
services.config.updateConfig(configValues) or comment/remove the call and add a
TODO and revert to the last supported SDK behavior; additionally update
ee/packages/federation-matrix/package.json to pin the dependency to the correct
released SDK version (or update the constraint to ^0.2.0 once the SDK is
published) so the code and package.json remain consistent.

Copy link
Contributor Author

@ricardogarim ricardogarim Oct 27, 2025

Choose a reason for hiding this comment

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

@coderabbitai, the library exists in the Homeserver project (PR #289), and once it’s reviewed there, we’ll release an update to bump the library version here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!


registerEvents(eventHandler, serverName, {
typing: processEDUTyping,
presence: processEDUPresence,
});

return true;
}
Loading