Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
5 changes: 5 additions & 0 deletions .changeset/moody-ghosts-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Don't use the registration.yaml file to configure Matrix Federation anymore.
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ export class MatrixBridge implements IFederationBridge {
// Dynamic import to prevent Rocket.Chat from loading the module until needed and then handle if that fails
const { Bridge, AppServiceRegistration, MatrixUser } = await import('@rocket.chat/forked-matrix-appservice-bridge');
MatrixUserInstance = MatrixUser;
const registrationFile = this.internalSettings.generateRegistrationFileObject();
const registrationFile = this.internalSettings.getAppServiceRegistrationObject();

this.bridgeInstance = new Bridge({
homeserverUrl: this.internalSettings.getHomeServerUrl(),
Expand All @@ -729,7 +729,7 @@ export class MatrixBridge implements IFederationBridge {
onLog: (line, isError) => {
console.log(line, isError);
},
...(this.internalSettings.generateRegistrationFileObject().enableEphemeralEvents
...(this.internalSettings.getAppServiceRegistrationObject().enableEphemeralEvents
? {
onEphemeralEvent: (request) => {
const event = request.getData() as unknown as AbstractMatrixEvent;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import crypto from 'crypto';
import fs from 'fs';
import { resolve } from 'path';

import { Settings } from '@rocket.chat/models';
import yaml from 'js-yaml';
Expand All @@ -16,7 +14,6 @@ export class RocketChatSettingsAdapter {
public async initialize() {
await this.addFederationSettings();
this.watchChangesAndUpdateRegistrationFile();
await this.updateSettingsWithProvidedConfigFileIfNecessary();
}

public getApplicationServiceId(): string {
Expand Down Expand Up @@ -65,12 +62,8 @@ export class RocketChatSettingsAdapter {
return settings.get('Federation_Matrix_enabled') === true;
}

public areEphemeralEventsEnabled(): boolean {
return this.isTypingStatusEnabled();
}

public isTypingStatusEnabled(): boolean {
return this.getRegistrationFileFromHomeserver()?.enableEphemeralEvents === true;
return settings.get('Federation_Matrix_enable_ephemeral_events') === true;
}

public onFederationEnabledStatusChanged(
Expand Down Expand Up @@ -103,19 +96,19 @@ export class RocketChatSettingsAdapter {
this.getHomeServerDomain(),
this.getBridgeUrl(),
this.getBridgePort(),
this.generateRegistrationFileObject(),
this.getAppServiceRegistrationObject(),
),
);
}

public generateRegistrationFileObject(): IFederationBridgeRegistrationFile {
public getAppServiceRegistrationObject(): IFederationBridgeRegistrationFile {
return {
id: this.getApplicationServiceId(),
homeserverToken: this.getApplicationHomeServerToken(),
applicationServiceToken: this.getApplicationApplicationServiceToken(),
bridgeUrl: this.getBridgeUrl(),
botName: this.getBridgeBotUsername(),
enableEphemeralEvents: this.areEphemeralEventsEnabled(),
enableEphemeralEvents: this.isTypingStatusEnabled(),
listenTo: {
users: [
{
Expand All @@ -140,7 +133,7 @@ export class RocketChatSettingsAdapter {
}

private async updateRegistrationFile(): Promise<void> {
const registrationFile = this.generateRegistrationFileObject();
const registrationFile = this.getAppServiceRegistrationObject();

await Settings.updateValueById(
'Federation_Matrix_registration_file',
Expand Down Expand Up @@ -172,9 +165,7 @@ export class RocketChatSettingsAdapter {
}

private async addFederationSettings(): Promise<void> {
const preExistingConfiguration = this.getRegistrationFileFromHomeserver();

await settingsRegistry.add('Federation_Matrix_enabled', Boolean(preExistingConfiguration), {
await settingsRegistry.add('Federation_Matrix_enabled', false, {
readonly: false,
type: 'boolean',
i18nLabel: 'Federation_Matrix_enabled',
Expand All @@ -185,11 +176,24 @@ export class RocketChatSettingsAdapter {
section: 'Matrix Bridge',
});

await settingsRegistry.add('Federation_Matrix_enable_ephemeral_events', false, {
Comment thread
MarcosSpessatto marked this conversation as resolved.
readonly: false,
type: 'boolean',
i18nLabel: 'Federation_Matrix_enable_ephemeral_events',
i18nDescription: 'Federation_Matrix_enable_ephemeral_events_desc',
alert: 'Federation_Matrix_enable_ephemeral_events_Alert',
public: true,
group: 'Federation',
section: 'Matrix Bridge',
});

const uniqueId = settings.get('uniqueID') || uuidv4().slice(0, 15).replace(new RegExp('-', 'g'), '_');
const homeserverToken = crypto.createHash('sha256').update(`hs_${uniqueId}`).digest('hex');
const applicationServiceToken = crypto.createHash('sha256').update(`as_${uniqueId}`).digest('hex');

await settingsRegistry.add('Federation_Matrix_id', preExistingConfiguration?.id || `rocketchat_${uniqueId}`, {
const siteUrl = settings.get<string>('Site_Url');

await settingsRegistry.add('Federation_Matrix_id', `rocketchat_${uniqueId}`, {
readonly: true,
type: 'string',
i18nLabel: 'Federation_Matrix_id',
Expand All @@ -198,7 +202,7 @@ export class RocketChatSettingsAdapter {
section: 'Matrix Bridge',
});

await settingsRegistry.add('Federation_Matrix_hs_token', preExistingConfiguration?.homeserverToken || homeserverToken, {
await settingsRegistry.add('Federation_Matrix_hs_token', homeserverToken, {
readonly: true,
type: 'string',
i18nLabel: 'Federation_Matrix_hs_token',
Expand All @@ -207,7 +211,7 @@ export class RocketChatSettingsAdapter {
section: 'Matrix Bridge',
});

await settingsRegistry.add('Federation_Matrix_as_token', preExistingConfiguration?.applicationServiceToken || applicationServiceToken, {
await settingsRegistry.add('Federation_Matrix_as_token', applicationServiceToken, {
readonly: true,
type: 'string',
i18nLabel: 'Federation_Matrix_as_token',
Expand All @@ -216,41 +220,33 @@ export class RocketChatSettingsAdapter {
section: 'Matrix Bridge',
});

await settingsRegistry.add(
'Federation_Matrix_homeserver_url',
preExistingConfiguration?.rocketchat?.homeServerUrl || 'http://localhost:8008',
{
type: 'string',
i18nLabel: 'Federation_Matrix_homeserver_url',
i18nDescription: 'Federation_Matrix_homeserver_url_desc',
alert: 'Federation_Matrix_homeserver_url_alert',
group: 'Federation',
section: 'Matrix Bridge',
},
);
await settingsRegistry.add('Federation_Matrix_homeserver_url', 'http://localhost:8008', {
type: 'string',
i18nLabel: 'Federation_Matrix_homeserver_url',
i18nDescription: 'Federation_Matrix_homeserver_url_desc',
alert: 'Federation_Matrix_homeserver_url_alert',
group: 'Federation',
section: 'Matrix Bridge',
});

await settingsRegistry.add(
'Federation_Matrix_homeserver_domain',
preExistingConfiguration?.rocketchat?.domainName || 'local.rocket.chat',
{
type: 'string',
i18nLabel: 'Federation_Matrix_homeserver_domain',
i18nDescription: 'Federation_Matrix_homeserver_domain_desc',
alert: 'Federation_Matrix_homeserver_domain_alert',
group: 'Federation',
section: 'Matrix Bridge',
},
);
await settingsRegistry.add('Federation_Matrix_homeserver_domain', siteUrl, {
type: 'string',
i18nLabel: 'Federation_Matrix_homeserver_domain',
i18nDescription: 'Federation_Matrix_homeserver_domain_desc',
alert: 'Federation_Matrix_homeserver_domain_alert',
group: 'Federation',
section: 'Matrix Bridge',
});

await settingsRegistry.add('Federation_Matrix_bridge_url', preExistingConfiguration?.bridgeUrl || 'http://host.docker.internal:3300', {
await settingsRegistry.add('Federation_Matrix_bridge_url', 'http://localhost:3300', {
type: 'string',
i18nLabel: 'Federation_Matrix_bridge_url',
i18nDescription: 'Federation_Matrix_bridge_url_desc',
group: 'Federation',
section: 'Matrix Bridge',
});

await settingsRegistry.add('Federation_Matrix_bridge_localpart', preExistingConfiguration?.botName || 'rocket.cat', {
await settingsRegistry.add('Federation_Matrix_bridge_localpart', 'rocket.cat', {
type: 'string',
i18nLabel: 'Federation_Matrix_bridge_localpart',
i18nDescription: 'Federation_Matrix_bridge_localpart_desc',
Expand All @@ -260,7 +256,6 @@ export class RocketChatSettingsAdapter {

await settingsRegistry.add('Federation_Matrix_registration_file', '', {
readonly: true,
hidden: Boolean(preExistingConfiguration),
type: 'code',
i18nLabel: 'Federation_Matrix_registration_file',
i18nDescription: 'Federation_Matrix_registration_file_desc',
Expand All @@ -282,49 +277,4 @@ export class RocketChatSettingsAdapter {
section: 'Matrix Bridge',
});
}

private getRegistrationFileFromHomeserver(): Record<string, any> | undefined {
try {
const registrationYaml = fs.readFileSync(this.getFilePathForHomeserverConfig(), 'utf8');

const parsedFile = yaml.load(registrationYaml as string) as Record<string, any>;
return {
applicationServiceToken: parsedFile.as_token,
bridgeUrl: parsedFile.url,
botName: parsedFile.sender_localpart,
homeserverToken: parsedFile.hs_token,
id: parsedFile.id,
listenTo: parsedFile.namespaces,
enableEphemeralEvents: parsedFile['de.sorunome.msc2409.push_ephemeral'],
rocketchat: { domainName: parsedFile.rocketchat?.homeserver_domain, homeServerUrl: parsedFile.rocketchat?.homeserver_url },
};
} catch (e) {
// no-op
}
}

private getFilePathForHomeserverConfig(): string {
return process.env.NODE_ENV === 'development'
? '../../../../../matrix-federation-config/registration.yaml'
: resolve(process.cwd(), '../../../matrix-federation-config/registration.yaml');
}

private async updateSettingsWithProvidedConfigFileIfNecessary() {
const existingConfiguration = this.getRegistrationFileFromHomeserver();
if (!existingConfiguration) {
return;
}

await Promise.all([
Settings.updateValueById('Federation_Matrix_enabled', true),
Settings.updateValueById('Federation_Matrix_id', existingConfiguration.id),
Settings.updateValueById('Federation_Matrix_hs_token', existingConfiguration.homeserverToken),
Settings.updateValueById('Federation_Matrix_as_token', existingConfiguration.applicationServiceToken),
Settings.updateValueById('Federation_Matrix_homeserver_url', existingConfiguration.rocketchat?.homeServerUrl),
Settings.updateValueById('Federation_Matrix_homeserver_domain', existingConfiguration.rocketchat?.domainName),
Settings.updateValueById('Federation_Matrix_bridge_url', existingConfiguration.bridgeUrl),
Settings.updateValueById('Federation_Matrix_bridge_localpart', existingConfiguration.botName),
Settings.update({ _id: 'Federation_Matrix_registration_file' }, { $set: { hidden: Boolean(existingConfiguration) } }),
]);
}
}
2 changes: 2 additions & 0 deletions packages/i18n/src/locales/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -2244,6 +2244,8 @@
"Federation_Description": "Federation allows an unlimited number of workspaces to communicate with each other.",
"Federation_Enable": "Enable Federation",
"Federation_Example_matrix_server": "Example: matrix.org",
"Federation_Matrix_enable_ephemeral_events": "Enable Matrix ephemeral events",
"Federation_Matrix_enable_ephemeral_events_Alert": "This requires a restart. </br> Enabling ephemeral events like user typing indicator can affect the performance of your Matrix Homeserver and Rocket.Chat server for federated communication",
"Federation_Federated_room_search": "Federated room search",
"Federation_Public_key": "Public Key",
"Federation_Search_federated_rooms": "Search federated rooms",
Expand Down