Skip to content
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
7 changes: 0 additions & 7 deletions apps/meteor/app/api/server/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ const createApi = function _createApi(options: { version?: string; useDefaultAut
export const API: {
api: Router<'/api', any, APIActionHandler>;
v1: APIClass<'/v1'>;
_matrix: Router<'/_matrix', any, APIActionHandler>;
wellKnown: Router<'/.well-known', any, APIActionHandler>;
matrixInternal: Router<'/internal', any, APIActionHandler>;
default: APIClass;
ApiClass: typeof APIClass;
channels?: {
Expand Down Expand Up @@ -76,9 +73,6 @@ export const API: {
version: 'v1',
useDefaultAuth: true,
}),
_matrix: new RocketChatAPIRouter('/_matrix'),
wellKnown: new RocketChatAPIRouter('/.well-known'),
matrixInternal: new RocketChatAPIRouter('/internal'),
default: createApi({}),
};

Expand Down Expand Up @@ -106,7 +100,6 @@ settings.watch<number>('API_Enable_Rate_Limiter_Limit_Calls_Default', (value) =>
});

export const startRestAPI = () => {
// Register main API routes under /api prefix
(WebApp.rawConnectHandlers as unknown as ReturnType<typeof express>).use(
API.api
.use(remoteAddressMiddleware)
Expand Down
65 changes: 53 additions & 12 deletions ee/packages/federation-matrix/src/FederationMatrix.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import 'reflect-metadata';

import type { HomeserverEventSignatures, HomeserverServices, DependencyContainer } from '@hs/federation-sdk';
import { getAllServices } from '@hs/federation-sdk';
import { toUnpaddedBase64 } from '@hs/core';
import { ConfigService, createFederationContainer, getAllServices } from '@hs/federation-sdk';
import type { HomeserverEventSignatures, HomeserverServices, FederationContainerOptions } from '@hs/federation-sdk';
import { type IFederationMatrixService, ServiceClass, Settings } from '@rocket.chat/core-services';
import type { IMessage, IRoom, IUser } from '@rocket.chat/core-typings';
import { Emitter } from '@rocket.chat/emitter';
import { Router } from '@rocket.chat/http-router';
import { Logger } from '@rocket.chat/logger';
import { MatrixBridgedUser, MatrixBridgedRoom, Users } from '@rocket.chat/models';

import { getAllMatrixRoutes } from './api/api';
import { getWellKnownRoutes } from './api/.well-known/server';
import { getMatrixInviteRoutes } from './api/_matrix/invite';
import { getKeyServerRoutes } from './api/_matrix/key/server';
import { getMatrixProfilesRoutes } from './api/_matrix/profiles';
import { getMatrixRoomsRoutes } from './api/_matrix/rooms';
import { getMatrixSendJoinRoutes } from './api/_matrix/send-join';
import { getMatrixTransactionsRoutes } from './api/_matrix/transactions';
import { getFederationVersionsRoutes } from './api/_matrix/versions';
import { registerEvents } from './events';
import { setup } from './setupContainers';

export class FederationMatrix extends ServiceClass implements IFederationMatrixService {
protected name = 'federation-matrix';
Expand All @@ -21,22 +29,59 @@ export class FederationMatrix extends ServiceClass implements IFederationMatrixS

private matrixDomain: string;

private diContainer: DependencyContainer;

private readonly logger = new Logger(this.name);

private httpRoutes: { matrix: Router<'/_matrix'>; wellKnown: Router<'/.well-known'> };

private constructor(emitter?: Emitter<HomeserverEventSignatures>) {
super();
this.eventHandler = emitter || new Emitter<HomeserverEventSignatures>();
}

static async create(emitter?: Emitter<HomeserverEventSignatures>): Promise<FederationMatrix> {
const instance = new FederationMatrix(emitter);
instance.diContainer = await setup(instance.eventHandler);
const config = new ConfigService();
const matrixConfig = config.getMatrixConfig();
const serverConfig = config.getServerConfig();
const signingKeys = await config.getSigningKey();
const signingKey = signingKeys[0];

const containerOptions: FederationContainerOptions = {
emitter,
federationOptions: {
serverName: matrixConfig.serverName,
signingKey: toUnpaddedBase64(signingKey.privateKey),
signingKeyId: `ed25519:${signingKey.version}`,
timeout: 30000,
baseUrl: serverConfig.baseUrl,
},
};

await createFederationContainer(containerOptions);
instance.homeserverServices = getAllServices();
instance.buildMatrixHTTPRoutes();

return instance;
}

private buildMatrixHTTPRoutes() {
const matrix = new Router('/_matrix');
const wellKnown = new Router('/.well-known');

matrix
.use(getMatrixInviteRoutes(this.homeserverServices))
.use(getMatrixProfilesRoutes(this.homeserverServices))
.use(getMatrixRoomsRoutes(this.homeserverServices))
.use(getMatrixSendJoinRoutes(this.homeserverServices))
.use(getMatrixTransactionsRoutes(this.homeserverServices))
.use(getKeyServerRoutes(this.homeserverServices))
.use(getFederationVersionsRoutes());

wellKnown.use(getWellKnownRoutes(this.homeserverServices));

this.httpRoutes = { matrix, wellKnown };
}

async created(): Promise<void> {
try {
registerEvents(this.eventHandler);
Expand All @@ -58,12 +103,8 @@ export class FederationMatrix extends ServiceClass implements IFederationMatrixS
return this.matrixDomain;
}

async started(): Promise<void> {
this.homeserverServices = getAllServices(this.diContainer);
}

getAllRoutes() {
return getAllMatrixRoutes();
return this.httpRoutes;
}

async createRoom(room: IRoom, owner: IUser, members: string[]): Promise<void> {
Expand Down
13 changes: 7 additions & 6 deletions ee/packages/federation-matrix/src/api/.well-known/server.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { Router } from "@rocket.chat/http-router";
import { Router } from "@rocket.chat/http-router";
import { ajv } from '@rocket.chat/rest-typings/dist/v1/Ajv';
import { getAllServicesFromFederationSDK } from '../../setupContainers';
import { createHash } from 'node:crypto';

import type { HomeserverServices } from '@hs/federation-sdk';

const WellKnownServerResponseSchema = {
type: 'object',
properties: {
Expand All @@ -16,10 +17,10 @@ const WellKnownServerResponseSchema = {

const isWellKnownServerResponseProps = ajv.compile(WellKnownServerResponseSchema);

export const getWellKnownRoutes = (router: Router<'/.well-known'>) => {
const { wellKnown } = getAllServicesFromFederationSDK();
return router.get('/matrix/server', {
export const getWellKnownRoutes = (services: HomeserverServices) => {
const { wellKnown } = services;

return new Router('/matrix').get('/server', {
response: {
200: isWellKnownServerResponseProps
},
Expand Down
13 changes: 6 additions & 7 deletions ee/packages/federation-matrix/src/api/_matrix/invite.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type { Router } from '@rocket.chat/http-router';
import type { HomeserverServices } from '@hs/federation-sdk';
import { Router } from '@rocket.chat/http-router';
import { ajv } from '@rocket.chat/rest-typings/dist/v1/Ajv';

import { getAllServicesFromFederationSDK } from '../../setupContainers';

const EventBaseSchema = {
type: 'object',
properties: {
Expand Down Expand Up @@ -127,11 +126,11 @@ const ProcessInviteResponseSchema = {

const isProcessInviteResponseProps = ajv.compile(ProcessInviteResponseSchema);

export const getMatrixInviteRoutes = (router: Router<'/_matrix'>) => {
const { invite } = getAllServicesFromFederationSDK();
export const getMatrixInviteRoutes = (services: HomeserverServices) => {
const { invite } = services;

return router.put(
'/federation/v2/invite/:roomId/:eventId',
return new Router('/federation').put(
'/v2/invite/:roomId/:eventId',
{
body: isProcessInviteBodyProps,
params: isProcessInviteParamsProps,
Expand Down
13 changes: 6 additions & 7 deletions ee/packages/federation-matrix/src/api/_matrix/key/server.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type { Router } from '@rocket.chat/http-router';
import type { HomeserverServices } from '@hs/federation-sdk';
import { Router } from '@rocket.chat/http-router';
import { ajv } from '@rocket.chat/rest-typings/dist/v1/Ajv';

import { getAllServicesFromFederationSDK } from '../../../setupContainers';

const ServerKeyResponseSchema = {
type: 'object',
properties: {
Expand Down Expand Up @@ -33,11 +32,11 @@ const ServerKeyResponseSchema = {

const isServerKeyResponseProps = ajv.compile(ServerKeyResponseSchema);

export const getKeyServerRoutes = (router: Router<'/_matrix'>) => {
const { server } = getAllServicesFromFederationSDK();
export const getKeyServerRoutes = (services: HomeserverServices) => {
const { server } = services;

return router.get(
'/key/v2/server',
return new Router('/key').get(
'/v2/server',
{
response: {
200: isServerKeyResponseProps,
Expand Down
23 changes: 11 additions & 12 deletions ee/packages/federation-matrix/src/api/_matrix/profiles.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type { Router } from '@rocket.chat/http-router';
import type { HomeserverServices } from '@hs/federation-sdk';
import { Router } from '@rocket.chat/http-router';
import { ajv } from '@rocket.chat/rest-typings/dist/v1/Ajv';

import { getAllServicesFromFederationSDK } from '../../setupContainers';

const UsernameSchema = {
type: 'string',
pattern: '^@[A-Za-z0-9_=\\/.+-]+:(.+)$',
Expand Down Expand Up @@ -330,12 +329,12 @@ const EventAuthResponseSchema = {

const isEventAuthResponseProps = ajv.compile(EventAuthResponseSchema);

export const getMatrixProfilesRoutes = (router: Router<'/_matrix'>) => {
const { profile } = getAllServicesFromFederationSDK();
export const getMatrixProfilesRoutes = (services: HomeserverServices) => {
const { profile } = services;

return router
return new Router('/federation')
.get(
'/federation/v1/query/profile',
'/v1/query/profile',
{
query: isQueryProfileQueryProps,
response: {
Expand All @@ -356,7 +355,7 @@ export const getMatrixProfilesRoutes = (router: Router<'/_matrix'>) => {
},
)
.post(
'/federation/v1/user/keys/query',
'/v1/user/keys/query',
{
body: isQueryKeysBodyProps,
response: {
Expand All @@ -377,7 +376,7 @@ export const getMatrixProfilesRoutes = (router: Router<'/_matrix'>) => {
},
)
.get(
'/federation/v1/user/devices/:userId',
'/v1/user/devices/:userId',
{
params: isGetDevicesParamsProps,
response: {
Expand All @@ -398,7 +397,7 @@ export const getMatrixProfilesRoutes = (router: Router<'/_matrix'>) => {
},
)
.get(
'/federation/v1/make_join/:roomId/:userId',
'/v1/make_join/:roomId/:userId',
{
params: isMakeJoinParamsProps,
query: isMakeJoinQueryProps,
Expand Down Expand Up @@ -438,7 +437,7 @@ export const getMatrixProfilesRoutes = (router: Router<'/_matrix'>) => {
},
)
.post(
'/federation/v1/get_missing_events/:roomId',
'/v1/get_missing_events/:roomId',
{
params: isGetMissingEventsParamsProps,
body: isGetMissingEventsBodyProps,
Expand All @@ -461,7 +460,7 @@ export const getMatrixProfilesRoutes = (router: Router<'/_matrix'>) => {
},
)
.get(
'/federation/v1/event_auth/:roomId/:eventId',
'/v1/event_auth/:roomId/:eventId',
{
params: isEventAuthParamsProps,
response: {
Expand Down
15 changes: 7 additions & 8 deletions ee/packages/federation-matrix/src/api/_matrix/rooms.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type { Router } from '@rocket.chat/http-router';
import type { HomeserverServices } from '@hs/federation-sdk';
import { Router } from '@rocket.chat/http-router';
import { ajv } from '@rocket.chat/rest-typings/dist/v1/Ajv';

import { getAllServicesFromFederationSDK } from '../../setupContainers';

const PublicRoomsQuerySchema = {
type: 'object',
properties: {
Expand Down Expand Up @@ -122,12 +121,12 @@ const PublicRoomsPostBodySchema = {

const isPublicRoomsPostBodyProps = ajv.compile(PublicRoomsPostBodySchema);

export const getMatrixRoomsRoutes = (router: Router<'/_matrix'>) => {
const { state } = getAllServicesFromFederationSDK();
export const getMatrixRoomsRoutes = (services: HomeserverServices) => {
const { state } = services;

return router
return new Router('/federation')
.get(
'/federation/v1/publicRooms',
'/v1/publicRooms',
{
query: isPublicRoomsQueryProps,
response: {
Expand Down Expand Up @@ -158,7 +157,7 @@ export const getMatrixRoomsRoutes = (router: Router<'/_matrix'>) => {
},
)
.post(
'/federation/v1/publicRooms',
'/v1/publicRooms',
{
body: isPublicRoomsPostBodyProps,
response: {
Expand Down
13 changes: 6 additions & 7 deletions ee/packages/federation-matrix/src/api/_matrix/send-join.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type { Router } from '@rocket.chat/http-router';
import type { HomeserverServices } from '@hs/federation-sdk';
import { Router } from '@rocket.chat/http-router';
import { ajv } from '@rocket.chat/rest-typings/dist/v1/Ajv';

import { getAllServicesFromFederationSDK } from '../../setupContainers';

const UsernameSchema = {
type: 'string',
pattern: '^@[A-Za-z0-9_=\\/.+-]+:(.+)$',
Expand Down Expand Up @@ -216,11 +215,11 @@ const SendJoinResponseSchema = {

const isSendJoinResponseProps = ajv.compile(SendJoinResponseSchema);

export const getMatrixSendJoinRoutes = (router: Router<'/_matrix'>) => {
const { sendJoin } = getAllServicesFromFederationSDK();
export const getMatrixSendJoinRoutes = (services: HomeserverServices) => {
const { sendJoin } = services;

return router.put(
'/federation/v2/send_join/:roomId/:stateKey',
return new Router('/federation').put(
'/v2/send_join/:roomId/:stateKey',
{
params: isSendJoinParamsProps,
body: isSendJoinEventProps,
Expand Down
13 changes: 6 additions & 7 deletions ee/packages/federation-matrix/src/api/_matrix/transactions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type { Router } from '@rocket.chat/http-router';
import type { HomeserverServices } from '@hs/federation-sdk';
import { Router } from '@rocket.chat/http-router';
import { ajv } from '@rocket.chat/rest-typings/dist/v1/Ajv';

import { getAllServicesFromFederationSDK } from '../../setupContainers';

const SendTransactionParamsSchema = {
type: 'object',
properties: {
Expand Down Expand Up @@ -155,11 +154,11 @@ const ErrorResponseSchema = {

const isErrorResponseProps = ajv.compile(ErrorResponseSchema);

export const getMatrixTransactionsRoutes = (router: Router<'/_matrix'>) => {
const { event } = getAllServicesFromFederationSDK();
export const getMatrixTransactionsRoutes = (services: HomeserverServices) => {
const { event } = services;

return router.put(
'/federation/v1/send/:txnId',
return new Router('/federation').put(
'/v1/send/:txnId',
{
params: isSendTransactionParamsProps,
body: isSendTransactionBodyProps,
Expand Down
Loading
Loading