11import {
22 EventBase ,
33 EventStore ,
4- RoomPowerLevelsEvent ,
54 SignedEvent ,
65 TombstoneAuthEvents ,
76 createLogger ,
@@ -23,18 +22,18 @@ import {
2322 RoomVersion ,
2423 UserID ,
2524 extractDomainFromId ,
25+ StateResolverAuthorizationError ,
2626} from '@rocket.chat/federation-room' ;
2727import { delay , inject , singleton } from 'tsyringe' ;
2828
2929import { ConfigService } from './config.service' ;
30- import { EventAuthorizationService } from './event-authorization.service' ;
3130import { EventEmitterService } from './event-emitter.service' ;
3231import { EventFetcherService } from './event-fetcher.service' ;
3332import { EventService } from './event.service' ;
3433import { FederationValidationService } from './federation-validation.service' ;
3534import { FederationService } from './federation.service' ;
3635import { InviteService } from './invite.service' ;
37- import { RoomInfoNotReadyError , StateService , UnknownRoomError } from './state.service' ;
36+ import { StateService , UnknownRoomError } from './state.service' ;
3837import { EventStagingRepository } from '../repositories/event-staging.repository' ;
3938import { EventRepository } from '../repositories/event.repository' ;
4039import { RoomRepository } from '../repositories/room.repository' ;
@@ -105,42 +104,6 @@ export class RoomService {
105104 }
106105 }
107106
108- private validateKickPermission ( currentPowerLevelsContent : RoomPowerLevelsEvent [ 'content' ] , senderId : string , kickedUserId : string ) : void {
109- const senderPower = currentPowerLevelsContent . users ?. [ senderId ] ?? currentPowerLevelsContent . users_default ?? 0 ;
110- const kickedUserPower = currentPowerLevelsContent . users ?. [ kickedUserId ] ?? currentPowerLevelsContent . users_default ?? 0 ;
111- const kickLevel = currentPowerLevelsContent . kick ?? 50 ; // Default kick level if not specified
112-
113- if ( senderPower < kickLevel ) {
114- logger . warn ( `Sender ${ senderId } (power ${ senderPower } ) does not meet required power level (${ kickLevel } ) to kick users.` ) ;
115- throw new HttpException ( "You don't have permission to kick users from this room." , HttpStatus . FORBIDDEN ) ;
116- }
117-
118- if ( kickedUserPower >= senderPower ) {
119- logger . warn (
120- `Sender ${ senderId } (power ${ senderPower } ) cannot kick user ${ kickedUserId } (power ${ kickedUserPower } ) who has equal or greater power.` ,
121- ) ;
122- throw new HttpException ( 'You cannot kick a user with power greater than or equal to your own.' , HttpStatus . FORBIDDEN ) ;
123- }
124- }
125-
126- private validateBanPermission ( currentPowerLevelsContent : RoomPowerLevelsEvent [ 'content' ] , senderId : string , bannedUserId : string ) : void {
127- const senderPower = currentPowerLevelsContent . users ?. [ senderId ] ?? currentPowerLevelsContent . users_default ?? 0 ;
128- const bannedUserPower = currentPowerLevelsContent . users ?. [ bannedUserId ] ?? currentPowerLevelsContent . users_default ?? 0 ;
129- const banLevel = currentPowerLevelsContent . ban ?? 50 ; // Default ban level if not specified
130-
131- if ( senderPower < banLevel ) {
132- logger . warn ( `Sender ${ senderId } (power ${ senderPower } ) does not meet required power level (${ banLevel } ) to ban users.` ) ;
133- throw new HttpException ( "You don't have permission to ban users from this room." , HttpStatus . FORBIDDEN ) ;
134- }
135-
136- if ( bannedUserPower >= senderPower ) {
137- logger . warn (
138- `Sender ${ senderId } (power ${ senderPower } ) cannot ban user ${ bannedUserId } (power ${ bannedUserPower } ) who has equal or greater power.` ,
139- ) ;
140- throw new HttpException ( 'You cannot ban a user with power greater than or equal to your own.' , HttpStatus . FORBIDDEN ) ;
141- }
142- }
143-
144107 async upsertRoom ( roomId : string , state : EventBase [ ] ) {
145108 logger . info ( `Upserting room ${ roomId } with ${ state . length } state events` ) ;
146109
@@ -447,7 +410,14 @@ export class RoomService {
447410 PersistentEventFactory . defaultRoomVersion ,
448411 ) ;
449412
450- await this . stateService . handlePdu ( event ) ;
413+ try {
414+ await this . stateService . handlePdu ( event ) ;
415+ } catch ( error ) {
416+ if ( error instanceof StateResolverAuthorizationError ) {
417+ throw new HttpException ( error . reason , HttpStatus . FORBIDDEN ) ;
418+ }
419+ throw error ;
420+ }
451421
452422 logger . info ( `Successfully created and stored m.room.power_levels event ${ event . eventId } for room ${ roomId } ` ) ;
453423
@@ -557,21 +527,6 @@ export class RoomService {
557527
558528 const roomInfo = await this . stateService . getRoomInformation ( roomId ) ;
559529
560- const authEventIdsForPowerLevels = await this . eventService . getAuthEventIds ( 'm.room.power_levels' , { roomId, senderId } ) ;
561- const powerLevelsEventId = this . getEventByType ( authEventIdsForPowerLevels , 'm.room.power_levels' ) ?. _id ;
562-
563- if ( ! powerLevelsEventId ) {
564- logger . warn ( `No power_levels event found for room ${ roomId } , cannot verify permission to kick.` ) ;
565- throw new HttpException ( 'Cannot verify permission to kick user.' , HttpStatus . FORBIDDEN ) ;
566- }
567- const powerLevelsEvent = await this . eventService . getEventById ( powerLevelsEventId , 'm.room.power_levels' ) ;
568- if ( ! powerLevelsEvent ) {
569- logger . error ( `Power levels event ${ powerLevelsEventId } not found despite ID being retrieved.` ) ;
570- throw new HttpException ( 'Internal server error: Power levels event data missing.' , HttpStatus . INTERNAL_SERVER_ERROR ) ;
571- }
572-
573- this . validateKickPermission ( powerLevelsEvent . event . content , senderId , kickedUserId ) ;
574-
575530 const kickEvent = await this . stateService . buildEvent < 'm.room.member' > (
576531 {
577532 type : 'm.room.member' ,
@@ -590,14 +545,28 @@ export class RoomService {
590545 roomInfo . room_version ,
591546 ) ;
592547
593- await this . stateService . handlePdu ( kickEvent ) ;
548+ try {
549+ await this . stateService . handlePdu ( kickEvent ) ;
550+ } catch ( error ) {
551+ if ( error instanceof StateResolverAuthorizationError ) {
552+ logger . warn ( `User ${ senderId } failed to kick ${ kickedUserId } from room ${ roomId } : ${ error . reason } ` ) ;
553+
554+ throw new HttpException ( error . reason , HttpStatus . FORBIDDEN ) ;
555+ }
556+ throw error ;
557+ }
558+
559+ void this . federationService . sendEventToAllServersInRoom ( kickEvent ) ;
560+
561+ await this . emitterService . emit ( 'homeserver.matrix.membership' , {
562+ event_id : kickEvent . eventId ,
563+ event : kickEvent . event ,
564+ } ) ;
594565
595566 logger . info (
596567 `Successfully created and stored m.room.member (kick) event ${ kickEvent . eventId } for user ${ kickedUserId } in room ${ roomId } ` ,
597568 ) ;
598569
599- void this . federationService . sendEventToAllServersInRoom ( kickEvent ) ;
600-
601570 return kickEvent . eventId ;
602571 }
603572
@@ -648,22 +617,6 @@ export class RoomService {
648617
649618 const roomInfo = await this . stateService . getRoomInformation ( roomId ) ;
650619
651- const authEventIdsForPowerLevels = await this . eventService . getAuthEventIds ( 'm.room.power_levels' , { roomId, senderId } ) ;
652-
653- const powerLevelsEventId = this . getEventByType ( authEventIdsForPowerLevels , 'm.room.power_levels' ) ?. _id ;
654-
655- if ( ! powerLevelsEventId ) {
656- logger . warn ( `No power_levels event found for room ${ roomId } , cannot verify permission to ban.` ) ;
657- throw new HttpException ( 'Cannot verify permission to ban user.' , HttpStatus . FORBIDDEN ) ;
658- }
659- const powerLevelsEvent = await this . eventService . getEventById ( powerLevelsEventId , 'm.room.power_levels' ) ;
660- if ( ! powerLevelsEvent ) {
661- logger . error ( `Power levels event ${ powerLevelsEventId } not found despite ID being retrieved.` ) ;
662- throw new HttpException ( 'Internal server error: Power levels event data missing.' , HttpStatus . INTERNAL_SERVER_ERROR ) ;
663- }
664-
665- this . validateBanPermission ( powerLevelsEvent . event . content , senderId , bannedUserId ) ;
666-
667620 const banEvent = await this . stateService . buildEvent < 'm.room.member' > (
668621 {
669622 type : 'm.room.member' ,
@@ -682,7 +635,16 @@ export class RoomService {
682635 roomInfo . room_version ,
683636 ) ;
684637
685- await this . stateService . handlePdu ( banEvent ) ;
638+ try {
639+ await this . stateService . handlePdu ( banEvent ) ;
640+ } catch ( error ) {
641+ if ( error instanceof StateResolverAuthorizationError ) {
642+ logger . warn ( `User ${ senderId } failed to ban ${ bannedUserId } from room ${ roomId } : ${ error . reason } ` ) ;
643+
644+ throw new HttpException ( error . reason , HttpStatus . FORBIDDEN ) ;
645+ }
646+ throw error ;
647+ }
686648
687649 logger . info ( `Successfully created and stored m.room.member (ban) event ${ banEvent . eventId } for user ${ bannedUserId } in room ${ roomId } ` ) ;
688650
0 commit comments