diff --git a/ee/packages/federation-matrix/src/api/_matrix/transactions.ts b/ee/packages/federation-matrix/src/api/_matrix/transactions.ts index 27a58a054b8dc..31f94e0bd454f 100644 --- a/ee/packages/federation-matrix/src/api/_matrix/transactions.ts +++ b/ee/packages/federation-matrix/src/api/_matrix/transactions.ts @@ -3,6 +3,8 @@ import type { EventID } from '@hs/room'; import { Router } from '@rocket.chat/http-router'; import { ajv } from '@rocket.chat/rest-typings/dist/v1/Ajv'; +import { canAccessEvent } from '../middlewares'; + const SendTransactionParamsSchema = { type: 'object', properties: { @@ -252,7 +254,7 @@ const GetStateResponseSchema = { const isGetStateResponseProps = ajv.compile(GetStateResponseSchema); export const getMatrixTransactionsRoutes = (services: HomeserverServices) => { - const { event, config } = services; + const { event, federationAuth } = services; // PUT /_matrix/federation/v1/send/{txnId} return ( @@ -373,6 +375,7 @@ export const getMatrixTransactionsRoutes = (services: HomeserverServices) => { tags: ['Federation'], license: ['federation'], }, + canAccessEvent(federationAuth), async (c) => { const eventData = await event.getEventById(c.req.param('eventId') as EventID); if (!eventData) { @@ -387,8 +390,8 @@ export const getMatrixTransactionsRoutes = (services: HomeserverServices) => { return { body: { - origin_server_ts: new Date().getTime(), - origin: config.serverName, + origin_server_ts: eventData.event.origin_server_ts, + origin: eventData.origin, pdus: [eventData.event], }, statusCode: 200, diff --git a/ee/packages/federation-matrix/src/api/middlewares.ts b/ee/packages/federation-matrix/src/api/middlewares.ts new file mode 100644 index 0000000000000..bcfff8dada781 --- /dev/null +++ b/ee/packages/federation-matrix/src/api/middlewares.ts @@ -0,0 +1,33 @@ +import type { EventAuthorizationService } from '@hs/federation-sdk'; +import { errCodes } from '@hs/federation-sdk'; +import type { EventID } from '@hs/room'; +import type { Context, Next } from 'hono'; + +export const canAccessEvent = (federationAuth: EventAuthorizationService) => async (c: Context, next: Next) => { + try { + const url = new URL(c.req.url); + const path = url.search ? `${c.req.path}${url.search}` : c.req.path; + + const verificationResult = await federationAuth.canAccessEventFromAuthorizationHeader( + c.req.param('eventId') as EventID, + c.req.header('Authorization') || '', + c.req.method, + path, + undefined, + ); + + if (!verificationResult.authorized) { + return c.json( + { + errcode: errCodes[verificationResult.errorCode].errcode, + error: errCodes[verificationResult.errorCode].error, + }, + errCodes[verificationResult.errorCode].status, + ); + } + + return next(); + } catch (error) { + return c.json(errCodes.M_UNKNOWN, 500); + } +};