diff --git a/lib/src/room.dart b/lib/src/room.dart index 1b522d74..09b1bf8e 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -1930,13 +1930,41 @@ class Room { } } + /// Returns the room version if specified in the `m.room.create` state event. + String? get roomVersion => + getState(EventTypes.RoomCreate)?.content.tryGet('room_version'); + + /// Returns the creator's user ID of the room by fetching the sender of the + /// `m.room.create` event. + Set get creatorUserIds { + final creationEvent = getState(EventTypes.RoomCreate); + if (creationEvent == null) return {}; + final additionalCreators = + creationEvent.content.tryGetList('additional_creators') ?? []; + return { + creationEvent.senderId, + ...additionalCreators, + }; + } + /// Returns the power level of the given user ID. /// If a user_id is in the users list, then that user_id has the associated /// power level. Otherwise they have the default level users_default. /// If users_default is not supplied, it is assumed to be 0. If the room /// contains no m.room.power_levels event, the room’s creator has a power /// level of 100, and all other users have a power level of 0. + /// For room version 12 and above the room creator always has maximum + /// power level. int getPowerLevelByUserId(String userId) { + // Room creator has maximum power level: + if (creatorUserIds.contains(userId) && + !((int.tryParse(roomVersion ?? '') ?? 0) < 12)) { + // 2^53 - 1 from https://spec.matrix.org/v1.15/appendices/#canonical-json + const maxInteger = 9007199254740991; + + return maxInteger; + } + final powerLevelMap = getState(EventTypes.RoomPowerLevels)?.content; final userSpecificPowerLevel = diff --git a/test/room_test.dart b/test/room_test.dart index 0739afd0..2bf1b684 100644 --- a/test/room_test.dart +++ b/test/room_test.dart @@ -93,6 +93,18 @@ void main() { }, ); + room.setState( + Event( + content: {'room_version': '11'}, + eventId: '\$143273582443PhrSn:example.org', + originServerTs: DateTime.fromMillisecondsSinceEpoch(1432735824653), + senderId: '@example:example.org', + type: 'm.room.create', + unsigned: {'age': 1234}, + stateKey: '', + room: room, + ), + ); room.setState( Event( room: room, @@ -809,6 +821,17 @@ void main() { expect(room.canSendEvent('m.room.message'), true); final resp = await room.setPower('@test:fakeServer.notExisting', 0); expect(resp, '42'); + + // Creator has max power level from room version 12 on: + expect(room.creatorUserIds.contains('@example:example.org'), true); + expect(room.getPowerLevelByUserId('@example:example.org'), 0); + expect(room.roomVersion, '11'); + room.states[EventTypes.RoomCreate]!['']!.content['room_version'] = '12'; + expect(room.roomVersion, '12'); + expect( + room.getPowerLevelByUserId('@example:example.org'), + 9007199254740991, + ); }); test('invite', () async {