diff --git a/packages/federation-sdk/src/repositories/event.repository.ts b/packages/federation-sdk/src/repositories/event.repository.ts index 03b6a090a..927b2a91d 100644 --- a/packages/federation-sdk/src/repositories/event.repository.ts +++ b/packages/federation-sdk/src/repositories/event.repository.ts @@ -4,6 +4,7 @@ import { type EventID, Pdu, PduForType, + PduMembershipEvent, PduType, RejectCode, RoomID, @@ -125,14 +126,14 @@ export class EventRepository { public async findAllJoinedMembersEventsByRoomId( roomId: string, - ): Promise>[]> { + ): Promise>[]> { return this.collection .find({ 'event.room_id': roomId, 'event.type': 'm.room.member', 'event.content.membership': 'join', }) - .toArray() as Promise>[]>; + .toArray() as Promise>[]>; } async findLatestEventByRoomIdBeforeTimestampWithAssociatedState( @@ -188,13 +189,13 @@ export class EventRepository { findMembershipEventsFromDirectMessageRooms( users: string[], - ): FindCursor>> { + ): FindCursor>> { return this.collection.find({ 'event.type': 'm.room.member', 'event.state_key': { $in: users }, 'event.content.membership': { $in: ['join', 'invite'] }, 'event.content.is_direct': true, - }) as FindCursor>>; + }) as FindCursor>>; } findTombstoneEventsByRoomId(roomId: string): FindCursor { diff --git a/packages/federation-sdk/src/services/federation.service.ts b/packages/federation-sdk/src/services/federation.service.ts index 911f350aa..4af838fb2 100644 --- a/packages/federation-sdk/src/services/federation.service.ts +++ b/packages/federation-sdk/src/services/federation.service.ts @@ -3,7 +3,11 @@ import type { BaseEDU } from '@rocket.chat/federation-core'; import { createLogger } from '@rocket.chat/federation-core'; import { EventID, + EventPduTypeRoomMember, + EventPduTypeRoomMemberInvite, Pdu, + PduForType, + PduMembershipEvent, PersistentEventBase, PersistentEventFactory, extractDomainFromId, @@ -248,13 +252,17 @@ export class FederationService { ); } - return await this.requestService.put(residentServer, uri, { + const data = await this.requestService.put<{ + event: PduMembershipEvent<'invite'>; + }>(residentServer, uri, { event: inviteEvent.event, room_version: roomVersion, invite_room_state: await this.stateService.getStrippedRoomState( inviteEvent.roomId, ), }); + + return EventPduTypeRoomMemberInvite.parse(data.event); } async sendEventToAllServersInRoom(event: PersistentEventBase) { diff --git a/packages/federation-sdk/src/services/invite.service.ts b/packages/federation-sdk/src/services/invite.service.ts index 19117e496..870f45789 100644 --- a/packages/federation-sdk/src/services/invite.service.ts +++ b/packages/federation-sdk/src/services/invite.service.ts @@ -2,6 +2,7 @@ import { EventBase, createLogger } from '@rocket.chat/federation-core'; import { EventID, PduForType, + PduMembershipEvent, PersistentEventBase, PersistentEventFactory, RoomID, @@ -136,10 +137,7 @@ export class InviteService { // try to save // can only invite if already part of the room await stateService.handlePdu( - PersistentEventFactory.createFromRawEvent( - inviteResponse.event, - roomVersion, - ), + PersistentEventFactory.createFromRawEvent(inviteResponse, roomVersion), ); // let everyone know @@ -195,7 +193,7 @@ export class InviteService { } async processInvite( - event: PduForType<'m.room.member'>, + event: PduMembershipEvent<'invite'>, roomId: RoomID, eventId: EventID, roomVersion: RoomVersion, diff --git a/packages/federation-sdk/src/services/send-join.service.ts b/packages/federation-sdk/src/services/send-join.service.ts index 491ea19ab..52bdc3fa9 100644 --- a/packages/federation-sdk/src/services/send-join.service.ts +++ b/packages/federation-sdk/src/services/send-join.service.ts @@ -1,6 +1,7 @@ import { type EventID, PduForType, + PduMembershipEvent, getAuthChain, } from '@rocket.chat/federation-room'; import { singleton } from 'tsyringe'; @@ -23,7 +24,7 @@ export class SendJoinService { async sendJoin( roomId: string, eventId: EventID, - event: PduForType<'m.room.member'>, + event: PduMembershipEvent<'join'>, ) { const stateService = this.stateService; diff --git a/packages/room/src/types/_common.ts b/packages/room/src/types/_common.ts index c565145f8..ea5b13da4 100644 --- a/packages/room/src/types/_common.ts +++ b/packages/room/src/types/_common.ts @@ -1,5 +1,10 @@ import z from 'zod'; -import type { Pdu, PduType } from './v3-11'; +import type { + Pdu, + PduMembershipEventContent, + PduMembershipTypeSchema, + PduType, +} from './v3-11'; export type StateKey = string; @@ -25,4 +30,13 @@ export type StateEventIdMap = Map; export type PduForType

= Extract; +type MembershipType = z.infer; + +export type PduMembershipEvent = + Extract< + PduForType<'m.room.member'>, + // content.membership + { content: { membership: M } } + >; + export type PduCreate = PduForType<'m.room.create'>; diff --git a/packages/room/src/types/v3-11.ts b/packages/room/src/types/v3-11.ts index cfee2d9ac..522c784ea 100644 --- a/packages/room/src/types/v3-11.ts +++ b/packages/room/src/types/v3-11.ts @@ -656,12 +656,54 @@ export const EventPduTypeRoomCreate = z.object({ content: PduCreateEventContentSchema, }); -export const EventPduTypeRoomMember = z.object({ +export const EventPduTypeRoomMemberInvite = z.object({ ...PduNoContentStateEventSchema, type: z.literal('m.room.member'), - content: PduMembershipEventContentSchema, + content: PduMembershipEventContentSchema.extend({ + membership: z.literal('invite'), + }), +}); + +export const EventPduTypeRoomMemberJoin = z.object({ + ...PduNoContentStateEventSchema, + type: z.literal('m.room.member'), + content: PduMembershipEventContentSchema.extend({ + membership: z.literal('join'), + }), }); +export const EventPduTypeRoomMemberLeave = z.object({ + ...PduNoContentStateEventSchema, + type: z.literal('m.room.member'), + content: PduMembershipEventContentSchema.extend({ + membership: z.literal('leave'), + }), +}); + +export const EventPduTypeRoomMemberBan = z.object({ + ...PduNoContentStateEventSchema, + type: z.literal('m.room.member'), + content: PduMembershipEventContentSchema.extend({ + membership: z.literal('ban'), + }), +}); + +export const EventPduTypeRoomMemberKnock = z.object({ + ...PduNoContentStateEventSchema, + type: z.literal('m.room.member'), + content: PduMembershipEventContentSchema.extend({ + membership: z.literal('knock'), + }), +}); + +export const EventPduTypeRoomMember = z.union([ + EventPduTypeRoomMemberInvite, + EventPduTypeRoomMemberJoin, + EventPduTypeRoomMemberLeave, + EventPduTypeRoomMemberBan, + EventPduTypeRoomMemberKnock, +]); + export const EventPduTypeRoomJoinRules = z.object({ ...PduNoContentEmptyStateKeyStateEventSchema, type: z.literal('m.room.join_rules'), @@ -781,7 +823,12 @@ export const EventPduTypeRoomPinnedEvents = z.object({ export const PduStateEventSchema = z.discriminatedUnion('type', [ EventPduTypeRoomCreate, - EventPduTypeRoomMember, + // EventPduTypeRoomMember, + EventPduTypeRoomMemberInvite, + EventPduTypeRoomMemberJoin, + EventPduTypeRoomMemberLeave, + EventPduTypeRoomMemberBan, + EventPduTypeRoomMemberKnock, EventPduTypeRoomJoinRules,