From 48f59f378d46943adb7d5d7c0385643af8cf8be5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Thu, 17 Jul 2025 09:42:52 +0200 Subject: [PATCH 1/3] refactor: Restrict canChangeStateEvent, canInvite and canSendEvent to joined users --- lib/src/room.dart | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/src/room.dart b/lib/src/room.dart index c3efce20..8067c3fc 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -1989,6 +1989,7 @@ class Room { /// with possible overrides in `events`, if not present compares `ownPowerLevel` /// with state_default bool canChangeStateEvent(String action) { + if (membership != Membership.join) return false; return powerForChangingStateEvent(action) <= ownPowerLevel; } @@ -2060,10 +2061,14 @@ class Room { } /// The level required to invite a user. - bool get canInvite => - (getState(EventTypes.RoomPowerLevels)?.content.tryGet('invite') ?? - 0) <= - ownPowerLevel; + bool get canInvite { + if (membership != Membership.join) return false; + return (getState(EventTypes.RoomPowerLevels) + ?.content + .tryGet('invite') ?? + 0) <= + ownPowerLevel; + } /// The level required to kick a user. bool get canKick => @@ -2094,6 +2099,7 @@ class Room { /// The level required to send a certain event. Defaults to 0 if there is no /// events_default set or there is no power level state in the room. bool canSendEvent(String eventType) { + if (membership != Membership.join) return false; final powerLevelsMap = getState(EventTypes.RoomPowerLevels)?.content; final pl = powerLevelsMap From d3071ec5319b0ac039cd66137fed8bab6f47e2e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Thu, 17 Jul 2025 09:44:11 +0200 Subject: [PATCH 2/3] refactor: Restrict canRequestHistory to joined or archived rooms --- lib/src/timeline.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/src/timeline.dart b/lib/src/timeline.dart index 885b10b4..5ad7758d 100644 --- a/lib/src/timeline.dart +++ b/lib/src/timeline.dart @@ -80,6 +80,9 @@ class Timeline { bool _fetchedAllDatabaseEvents = false; bool get canRequestHistory { + if (!{Membership.join, Membership.leave}.contains(room.membership)) { + return false; + } if (events.isEmpty) return true; return !_fetchedAllDatabaseEvents || (room.prev_batch != null && events.last.type != EventTypes.RoomCreate); From 282ac54c7b9e2d944d48288e41cc34a1f810ce5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Thu, 17 Jul 2025 10:18:05 +0200 Subject: [PATCH 3/3] refactor: Restrict canKick canBan and canRedact to joined users --- lib/src/room.dart | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/src/room.dart b/lib/src/room.dart index 8067c3fc..1b522d74 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -1980,10 +1980,12 @@ class Room { } /// The level required to ban a user. - bool get canBan => - (getState(EventTypes.RoomPowerLevels)?.content.tryGet('ban') ?? - 50) <= - ownPowerLevel; + bool get canBan { + if (membership != Membership.join) return false; + return (getState(EventTypes.RoomPowerLevels)?.content.tryGet('ban') ?? + 50) <= + ownPowerLevel; + } /// returns if user can change a particular state event by comparing `ownPowerLevel` /// with possible overrides in `events`, if not present compares `ownPowerLevel` @@ -2071,16 +2073,22 @@ class Room { } /// The level required to kick a user. - bool get canKick => - (getState(EventTypes.RoomPowerLevels)?.content.tryGet('kick') ?? - 50) <= - ownPowerLevel; + bool get canKick { + if (membership != Membership.join) return false; + return (getState(EventTypes.RoomPowerLevels)?.content.tryGet('kick') ?? + 50) <= + ownPowerLevel; + } /// The level required to redact an event. - bool get canRedact => - (getState(EventTypes.RoomPowerLevels)?.content.tryGet('redact') ?? - 50) <= - ownPowerLevel; + bool get canRedact { + if (membership != Membership.join) return false; + return (getState(EventTypes.RoomPowerLevels) + ?.content + .tryGet('redact') ?? + 50) <= + ownPowerLevel; + } /// The default level required to send state events. Can be overridden by the events key. bool get canSendDefaultStates {