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

Regression: Fix federation Matrix bridge startup #25273

Merged
merged 1 commit into from
Apr 22, 2022
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
45 changes: 5 additions & 40 deletions apps/meteor/app/federation-v2/server/bridge.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,15 @@
import { Bridge, AppServiceRegistration } from 'matrix-appservice-bridge';

import { settings } from '../../settings/server';
import { IMatrixEvent } from './definitions/IMatrixEvent';
import { MatrixEventType } from './definitions/MatrixEventType';
import { addToQueue } from './queue';
import { config } from './config';

/* eslint-disable @typescript-eslint/camelcase */
const registrationConfig = AppServiceRegistration.fromObject({
id: config.id,
hs_token: config.hsToken,
as_token: config.asToken,
url: config.bridgeUrl,
sender_localpart: config.bridgeLocalpart,
namespaces: {
users: [
{
exclusive: false,
// Reserve these MXID's (usernames)
regex: `.*`,
},
],
aliases: [
{
exclusive: false,
// Reserve these room aliases
regex: `.*`,
},
],
rooms: [
{
exclusive: false,
// This regex is used to define which rooms we listen to with the bridge.
// This does not reserve the rooms like the other namespaces.
regex: '.*',
},
],
},
rate_limited: false,
protocols: null,
});
/* eslint-enable @typescript-eslint/camelcase */
import { getRegistrationInfo } from './config';

export const matrixBridge = new Bridge({
homeserverUrl: config.homeserverUrl,
domain: config.homeserverDomain,
registration: registrationConfig,
homeserverUrl: settings.get('Federation_Matrix_homeserver_url'),
domain: settings.get('Federation_Matrix_homeserver_domain'),
registration: AppServiceRegistration.fromObject(getRegistrationInfo()),
disableStores: true,
controller: {
onAliasQuery: (alias, matrixRoomId): void => {
Expand Down
63 changes: 37 additions & 26 deletions apps/meteor/app/federation-v2/server/config.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,43 @@
import type { AppServiceOutput } from 'matrix-appservice-bridge';

import { settings } from '../../settings/server';

type bridgeUrlString = `${string}://${string}:${string}`;
export type bridgeUrlTuple = [string, string, number];

interface IBridgeConfig {
id: string;
hsToken: string;
asToken: string;
homeserverUrl: string;
homeserverDomain: string;
bridgeUrl: bridgeUrlString;
bridgeLocalpart: string;
}

function _getConfig(): IBridgeConfig {
export function getRegistrationInfo(): AppServiceOutput {
/* eslint-disable @typescript-eslint/camelcase */
return {
id: settings.get('Federation_Matrix_id') as string,
hsToken: settings.get('Federation_Matrix_hs_token') as string,
asToken: settings.get('Federation_Matrix_as_token') as string,
homeserverUrl: settings.get('Federation_Matrix_homeserver_url') as string,
homeserverDomain: settings.get('Federation_Matrix_homeserver_domain') as string,
bridgeUrl: settings.get('Federation_Matrix_bridge_url') as bridgeUrlString,
bridgeLocalpart: settings.get('Federation_Matrix_bridge_localpart') as string,
} as IBridgeConfig;
}

export let config: IBridgeConfig = _getConfig();

export function getConfig() {
config = _getConfig();
id: settings.get('Federation_Matrix_id'),
hs_token: settings.get('Federation_Matrix_hs_token'),
as_token: settings.get('Federation_Matrix_as_token'),
url: settings.get<string>('Federation_Matrix_bridge_url'),
sender_localpart: settings.get('Federation_Matrix_bridge_localpart'),
namespaces: {
users: [
{
exclusive: false,
// Reserve these MXID's (usernames)
regex: `.*`,
},
],
aliases: [
{
exclusive: false,
// Reserve these room aliases
regex: `.*`,
},
],
rooms: [
{
exclusive: false,
// This regex is used to define which rooms we listen to with the bridge.
// This does not reserve the rooms like the other namespaces.
regex: '.*',
},
],
},
rate_limited: false,
protocols: null,
};
/* eslint-enable @typescript-eslint/camelcase */
}
20 changes: 1 addition & 19 deletions apps/meteor/app/federation-v2/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,2 @@
import { matrixBridge } from './bridge';
import { bridgeUrlTuple, config } from './config';
import { bridgeLogger } from './logger';
import './settings';
import { isFederationMatrixEnabled } from './tools';

((): void => {
if (!isFederationMatrixEnabled()) return;

bridgeLogger.info(`Running Federation V2:
id: ${config.id}
bridgeUrl: ${config.bridgeUrl}
homeserverURL: ${config.homeserverUrl}
homeserverDomain: ${config.homeserverDomain}
`);

const [, , port] = config.bridgeUrl.split(':') as bridgeUrlTuple;

matrixBridge.run(port);
})();
import './startup';
6 changes: 3 additions & 3 deletions apps/meteor/app/federation-v2/server/matrix-client/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { IUser } from '@rocket.chat/core-typings';
import { matrixBridge } from '../bridge';
import { MatrixBridgedUser, MatrixBridgedRoom, Users } from '../../../models/server';
import { addUserToRoom } from '../../../lib/server/functions';
import { config } from '../config';
import { matrixClient } from '.';
import { dataInterface } from '../data-interface';
import { settings } from '../../../settings/server';

interface ICreateUserResult {
uid: string;
Expand Down Expand Up @@ -52,7 +52,7 @@ export const invite = async (inviterId: string, roomId: string, invitedId: strin
// Determine if the user is local or remote
let invitedUserMatrixId = invitedId;
const invitedUserDomain = invitedId.includes(':') ? invitedId.split(':').pop() : '';
const invitedUserIsRemote = invitedUserDomain && invitedUserDomain !== config.homeserverDomain;
const invitedUserIsRemote = invitedUserDomain && invitedUserDomain !== settings.get('Federation_Matrix_homeserver_domain');

// Find the invited user in Rocket.Chats users
let invitedUser = Users.findOneByUsername(invitedId.replace('@', ''));
Expand Down Expand Up @@ -100,7 +100,7 @@ export const invite = async (inviterId: string, roomId: string, invitedId: strin
};

export const createRemote = async (u: IUser): Promise<ICreateUserResult> => {
const matrixUserId = `@${u.username?.toLowerCase()}:${config.homeserverDomain}`;
const matrixUserId = `@${u.username?.toLowerCase()}:${settings.get('Federation_Matrix_homeserver_domain')}`;

console.log(`Creating remote user ${matrixUserId}...`);

Expand Down
76 changes: 0 additions & 76 deletions apps/meteor/app/federation-v2/server/settings.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import yaml from 'js-yaml';
import { SHA256 } from 'meteor/sha';

import { settings, settingsRegistry } from '../../settings/server';
import { Settings } from '../../models/server/raw';
import { setupLogger } from './logger';
import { getConfig, config } from './config';

settingsRegistry.addGroup('Federation', function () {
this.section('Matrix Bridge', async function () {
Expand Down Expand Up @@ -64,77 +60,5 @@ settingsRegistry.addGroup('Federation', function () {
i18nLabel: 'Federation_Matrix_bridge_localpart',
i18nDescription: 'Federation_Matrix_bridge_localpart_desc',
});

this.add('Federation_Matrix_registration_file', '', {
readonly: true,
type: 'code',
i18nLabel: 'Federation_Matrix_registration_file',
i18nDescription: 'Federation_Matrix_registration_file_desc',
});
});
});

let registrationFile = {};

const updateRegistrationFile = async function (): Promise<void> {
// Refresh config
getConfig();

let { bridgeUrl } = config;

if (!bridgeUrl.includes(':')) {
bridgeUrl = `${bridgeUrl}:3300`;
}

/* eslint-disable @typescript-eslint/camelcase */
registrationFile = {
id: config.id,
hs_token: config.hsToken,
as_token: config.asToken,
url: bridgeUrl,
sender_localpart: config.bridgeLocalpart,
namespaces: {
users: [
{
exclusive: false,
regex: '.*',
},
],
rooms: [
{
exclusive: false,
regex: '.*',
},
],
aliases: [
{
exclusive: false,
regex: '.*',
},
],
},
};
/* eslint-enable @typescript-eslint/camelcase */

// Update the registration file
await Settings.updateValueById('Federation_Matrix_registration_file', yaml.dump(registrationFile));
};

// TODO: Changes here should re-initialize the bridge instead of needing a restart
// Add settings listeners
settings.watch('Federation_Matrix_enabled', (value) => {
setupLogger.info(`Federation Matrix is ${value ? 'enabled' : 'disabled'}`);
});

settings.watchMultiple(
[
'Federation_Matrix_id',
'Federation_Matrix_hs_token',
'Federation_Matrix_as_token',
'Federation_Matrix_homeserver_url',
'Federation_Matrix_homeserver_domain',
'Federation_Matrix_bridge_url',
'Federation_Matrix_bridge_localpart',
],
updateRegistrationFile,
);
26 changes: 26 additions & 0 deletions apps/meteor/app/federation-v2/server/startup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { settings } from '../../settings/server';
import { matrixBridge } from './bridge';
import { bridgeUrlTuple } from './config';
import { bridgeLogger, setupLogger } from './logger';
import { isFederationMatrixEnabled } from './tools';

((): void => {
if (!isFederationMatrixEnabled()) return;

bridgeLogger.info(`Running Federation V2:
id: ${settings.get('Federation_Matrix_id')}
bridgeUrl: ${settings.get<string>('Federation_Matrix_bridge_url')}
homeserverURL: ${settings.get('Federation_Matrix_homeserver_url')}
homeserverDomain: ${settings.get('Federation_Matrix_homeserver_domain')}
`);

const [, , port] = settings.get<string>('Federation_Matrix_bridge_url').split(':') as bridgeUrlTuple;

matrixBridge.run(port);

// TODO: Changes here should re-initialize the bridge instead of needing a restart
// Add settings listeners
settings.watch('Federation_Matrix_enabled', (value) => {
setupLogger.info(`Federation Matrix is ${value ? 'enabled' : 'disabled'}`);
});
})();
2 changes: 1 addition & 1 deletion apps/meteor/app/federation-v2/server/tools.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { settings } from '../../settings/server';
import { matrixBridge } from './bridge';

export const isFederationMatrixEnabled = () => settings.get('Federation_Matrix_enabled') && matrixBridge;
export const isFederationMatrixEnabled = (): boolean => !!(settings.get('Federation_Matrix_enabled') && matrixBridge);
1 change: 0 additions & 1 deletion apps/meteor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@
"@types/fibers": "^3.1.1",
"@types/google-libphonenumber": "^7.4.21",
"@types/imap": "^0.8.35",
"@types/js-yaml": "^4.0.5",
"@types/jsdom": "^16.2.12",
"@types/jsdom-global": "^3.0.2",
"@types/jsrsasign": "^9.0.3",
Expand Down
8 changes: 0 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3690,7 +3690,6 @@ __metadata:
"@types/fibers": ^3.1.1
"@types/google-libphonenumber": ^7.4.21
"@types/imap": ^0.8.35
"@types/js-yaml": ^4.0.5
"@types/jsdom": ^16.2.12
"@types/jsdom-global": ^3.0.2
"@types/jsrsasign": ^9.0.3
Expand Down Expand Up @@ -5818,13 +5817,6 @@ __metadata:
languageName: node
linkType: hard

"@types/js-yaml@npm:^4.0.5":
version: 4.0.5
resolution: "@types/js-yaml@npm:4.0.5"
checksum: 7dcac8c50fec31643cc9d6444b5503239a861414cdfaa7ae9a38bc22597c4d850c4b8cec3d82d73b3fbca408348ce223b0408d598b32e094470dfffc6d486b4d
languageName: node
linkType: hard

"@types/jsdom-global@npm:^3.0.2":
version: 3.0.2
resolution: "@types/jsdom-global@npm:3.0.2"
Expand Down