From 1b317479f61a61330cdace8fe985c08dab8cdc92 Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Wed, 10 Sep 2025 20:55:11 -0300 Subject: [PATCH 1/4] feat: adds get event by id route --- .../federation/transactions.controller.ts | 46 ++++++++++++++++++- .../src/dtos/federation/transactions.dto.ts | 19 ++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/packages/homeserver/src/controllers/federation/transactions.controller.ts b/packages/homeserver/src/controllers/federation/transactions.controller.ts index 8f1b2b10c..6c69426de 100644 --- a/packages/homeserver/src/controllers/federation/transactions.controller.ts +++ b/packages/homeserver/src/controllers/federation/transactions.controller.ts @@ -1,15 +1,20 @@ -import { EventService } from '@hs/federation-sdk'; +import { ConfigService, EventService } from '@hs/federation-sdk'; import { Elysia } from 'elysia'; import { container } from 'tsyringe'; import { ErrorResponseDto, + GetEventErrorResponseDto, + GetEventParamsDto, + GetEventResponseDto, SendTransactionBodyDto, SendTransactionResponseDto, } from '../../dtos'; export const transactionsPlugin = (app: Elysia) => { const eventService = container.resolve(EventService); - return app.put( + const configService = container.resolve(ConfigService); + + app.put( '/_matrix/federation/v1/send/:txnId', async ({ body }) => { // TODO need to validate better the payload @@ -34,4 +39,41 @@ export const transactionsPlugin = (app: Elysia) => { }, }, ); + + app.get( + '/_matrix/federation/v1/event/:eventId', + async ({ params, set }) => { + const eventData = await eventService.getEventById(params.eventId); + if (!eventData) { + set.status = 404; + return { + errcode: 'M_NOT_FOUND', + error: 'Event not found', + }; + } + + return { + origin_server_ts: eventData.event.origin_server_ts, + origin: configService.serverName, + pdus: [{ ...eventData.event, origin: configService.serverName }], + }; + }, + { + params: GetEventParamsDto, + response: { + 200: GetEventResponseDto, + 401: GetEventErrorResponseDto, + 403: GetEventErrorResponseDto, + 404: GetEventErrorResponseDto, + 500: GetEventErrorResponseDto, + }, + detail: { + tags: ['Federation'], + summary: 'Get event', + description: 'Get an event', + }, + }, + ); + + return app; }; diff --git a/packages/homeserver/src/dtos/federation/transactions.dto.ts b/packages/homeserver/src/dtos/federation/transactions.dto.ts index 58e2e7a71..54849fe3a 100644 --- a/packages/homeserver/src/dtos/federation/transactions.dto.ts +++ b/packages/homeserver/src/dtos/federation/transactions.dto.ts @@ -29,6 +29,25 @@ export const SendTransactionResponseDto = t.Object({ }), }); +export const GetEventParamsDto = t.Object({ + eventId: t.String({ description: 'Event ID' }), +}); + +export const GetEventResponseDto = t.Object({ + origin_server_ts: t.Number({ description: 'Origin server timestamp' }), + origin: t.String({ description: 'Origin server' }), + pdus: t.Array(EventBaseDto, { + description: 'An array containing a single PDU', + }), +}); + +export const GetEventErrorResponseDto = t.Object({ + errcode: t.String({ description: 'Error code' }), + error: t.String({ description: 'Error message' }), +}); + export type SendTransactionParams = Static; export type SendTransactionBody = Static; export type SendTransactionResponse = Static; +export type GetEventParams = Static; +export type GetEventResponse = Static; From 961c95e47353e9d4cf23c88d6956171bc3b88c2c Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Mon, 15 Sep 2025 12:00:24 -0300 Subject: [PATCH 2/4] chore: makes routes chained --- .../federation/transactions.controller.ts | 91 +++++++++---------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/packages/homeserver/src/controllers/federation/transactions.controller.ts b/packages/homeserver/src/controllers/federation/transactions.controller.ts index 6c69426de..0c84e03bd 100644 --- a/packages/homeserver/src/controllers/federation/transactions.controller.ts +++ b/packages/homeserver/src/controllers/federation/transactions.controller.ts @@ -21,59 +21,58 @@ export const transactionsPlugin = (app: Elysia) => { // biome-ignore lint/suspicious/noExplicitAny: await eventService.processIncomingTransaction(body as any); - return { - pdus: {}, - edus: {}, - }; - }, - { - body: SendTransactionBodyDto, - response: { - 200: SendTransactionResponseDto, - 400: ErrorResponseDto, + return { + pdus: {}, + edus: {}, + }; }, - detail: { - tags: ['Federation'], - summary: 'Send transaction', - description: 'Send a transaction', + { + body: SendTransactionBodyDto, + response: { + 200: SendTransactionResponseDto, + 400: ErrorResponseDto, + }, + detail: { + tags: ['Federation'], + summary: 'Send transaction', + description: 'Send a transaction', + }, }, - }, - ); + ) + .get( + '/_matrix/federation/v1/event/:eventId', + async ({ params, set }) => { + const eventData = await eventService.getEventById(params.eventId); + if (!eventData) { + set.status = 404; + return { + errcode: 'M_NOT_FOUND', + error: 'Event not found', + }; + } - app.get( - '/_matrix/federation/v1/event/:eventId', - async ({ params, set }) => { - const eventData = await eventService.getEventById(params.eventId); - if (!eventData) { - set.status = 404; return { - errcode: 'M_NOT_FOUND', - error: 'Event not found', + origin_server_ts: eventData.event.origin_server_ts, + origin: configService.serverName, + pdus: [{ ...eventData.event, origin: configService.serverName }], }; - } - - return { - origin_server_ts: eventData.event.origin_server_ts, - origin: configService.serverName, - pdus: [{ ...eventData.event, origin: configService.serverName }], - }; - }, - { - params: GetEventParamsDto, - response: { - 200: GetEventResponseDto, - 401: GetEventErrorResponseDto, - 403: GetEventErrorResponseDto, - 404: GetEventErrorResponseDto, - 500: GetEventErrorResponseDto, }, - detail: { - tags: ['Federation'], - summary: 'Get event', - description: 'Get an event', + { + params: GetEventParamsDto, + response: { + 200: GetEventResponseDto, + 401: GetEventErrorResponseDto, + 403: GetEventErrorResponseDto, + 404: GetEventErrorResponseDto, + 500: GetEventErrorResponseDto, + }, + detail: { + tags: ['Federation'], + summary: 'Get event', + description: 'Get an event', + }, }, - }, - ); + ); return app; }; From 62a1d9531ce2b4b090f9468483ff8b0bf8584580 Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Mon, 15 Sep 2025 12:02:23 -0300 Subject: [PATCH 3/4] chore: makes routes chained --- .../src/controllers/federation/transactions.controller.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/homeserver/src/controllers/federation/transactions.controller.ts b/packages/homeserver/src/controllers/federation/transactions.controller.ts index 0c84e03bd..d8348f845 100644 --- a/packages/homeserver/src/controllers/federation/transactions.controller.ts +++ b/packages/homeserver/src/controllers/federation/transactions.controller.ts @@ -73,6 +73,4 @@ export const transactionsPlugin = (app: Elysia) => { }, }, ); - - return app; }; From a47b32ab6d349e1fb1e15bcaa597d1cb7dc5e288 Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Mon, 15 Sep 2025 12:12:47 -0300 Subject: [PATCH 4/4] chore: makes routes chained --- .../federation/transactions.controller.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/homeserver/src/controllers/federation/transactions.controller.ts b/packages/homeserver/src/controllers/federation/transactions.controller.ts index d8348f845..9435f4e06 100644 --- a/packages/homeserver/src/controllers/federation/transactions.controller.ts +++ b/packages/homeserver/src/controllers/federation/transactions.controller.ts @@ -14,12 +14,13 @@ export const transactionsPlugin = (app: Elysia) => { const eventService = container.resolve(EventService); const configService = container.resolve(ConfigService); - app.put( - '/_matrix/federation/v1/send/:txnId', - async ({ body }) => { - // TODO need to validate better the payload - // biome-ignore lint/suspicious/noExplicitAny: - await eventService.processIncomingTransaction(body as any); + return app + .put( + '/_matrix/federation/v1/send/:txnId', + async ({ body }) => { + // TODO need to validate better the payload + // biome-ignore lint/suspicious/noExplicitAny: + await eventService.processIncomingTransaction(body as any); return { pdus: {},