diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectedRoomsEditor.razor b/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectedRoomsEditor.razor
index 51f8e1b..215ead3 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectedRoomsEditor.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectedRoomsEditor.razor
@@ -1,10 +1,10 @@
@page "/Moderation/DraupnirProtectedRoomsEditor"
@page "/Tools/Moderation/DraupnirProtectedRoomsEditor"
@page "/Tools/Moderation/Draupnir/ProtectedRoomsEditor"
-@using System.Text.Json.Serialization
@using LibMatrix
@using LibMatrix.EventTypes.Interop.Draupnir
@using LibMatrix.EventTypes.Spec.State
+@using LibMatrix.EventTypes.Spec.State.RoomInfo
@using LibMatrix.RoomTypes
<h3>Edit Draupnir protected rooms</h3>
<hr/>
@@ -43,7 +43,7 @@
</td>
<td>@(room.PowerLevels.Kick <= room.PowerLevels.GetUserPowerLevel(hs.UserId) ? "X" : "")</td>
<td>@(room.PowerLevels.Ban <= room.PowerLevels.GetUserPowerLevel(hs.UserId) ? "X" : "")</td>
- <td>@(room.PowerLevels.UserHasStatePermission(hs.UserId, RoomServerACLEventContent.EventId) ? "X" : "")</td>
+ <td>@(room.PowerLevels.UserHasStatePermission(hs.UserId, RoomServerAclEventContent.EventId) ? "X" : "")</td>
<td>@room.Room.RoomId</td>
<td>@room.RoomName</td>
</tr>
@@ -63,7 +63,7 @@
private AuthenticatedHomeserverGeneric hs { get; set; }
protected override async Task OnInitializedAsync() {
- hs = await RMUStorage.GetCurrentSessionOrNavigate();
+ hs = await RmuStorage.GetCurrentSessionOrNavigate();
if (hs is null) return;
data = await hs.GetAccountDataAsync<DraupnirProtectedRoomsData>(DraupnirProtectedRoomsData.EventId);
StateHasChanged();
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectionsEditor.razor b/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectionsEditor.razor
index b722596..da84def 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectionsEditor.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectionsEditor.razor
@@ -2,6 +2,7 @@
@using System.Text.Json.Serialization
@using LibMatrix
@using LibMatrix.EventTypes.Spec.State
+@using LibMatrix.EventTypes.Spec.State.RoomInfo
@using LibMatrix.RoomTypes
<h3>Edit Draupnir protected rooms</h3>
<hr/>
@@ -38,7 +39,7 @@
</td>
<td>@(room.PowerLevels.Kick <= room.PowerLevels.GetUserPowerLevel(hs.UserId) ? "X" : "")</td>
<td>@(room.PowerLevels.Ban <= room.PowerLevels.GetUserPowerLevel(hs.UserId) ? "X" : "")</td>
- <td>@(room.PowerLevels.UserHasStatePermission(hs.UserId, RoomServerACLEventContent.EventId) ? "X" : "")</td>
+ <td>@(room.PowerLevels.UserHasStatePermission(hs.UserId, RoomServerAclEventContent.EventId) ? "X" : "")</td>
<td>@room.Room.RoomId</td>
<td>@room.RoomName</td>
</tr>
@@ -58,7 +59,7 @@
private AuthenticatedHomeserverGeneric hs { get; set; }
protected override async Task OnInitializedAsync() {
- hs = await RMUStorage.GetCurrentSessionOrNavigate();
+ hs = await RmuStorage.GetCurrentSessionOrNavigate();
if (hs is null) return;
data = await hs.GetAccountDataAsync<DraupnirProtectedRoomsData>("org.matrix.mjolnir.protected_rooms");
StateHasChanged();
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirWatchedListsEditor.razor b/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirWatchedListsEditor.razor
index b2f4026..4aa0d2f 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirWatchedListsEditor.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirWatchedListsEditor.razor
@@ -2,6 +2,7 @@
@using System.Text.Json.Serialization
@using LibMatrix
@using LibMatrix.EventTypes.Spec.State
+@using LibMatrix.EventTypes.Spec.State.RoomInfo
@using LibMatrix.RoomTypes
<h3>Edit Draupnir protected rooms</h3>
<hr/>
@@ -38,7 +39,7 @@
</td>
<td>@(room.PowerLevels.Kick <= room.PowerLevels.GetUserPowerLevel(hs.UserId) ? "X" : "")</td>
<td>@(room.PowerLevels.Ban <= room.PowerLevels.GetUserPowerLevel(hs.UserId) ? "X" : "")</td>
- <td>@(room.PowerLevels.UserHasStatePermission(hs.UserId, RoomServerACLEventContent.EventId) ? "X" : "")</td>
+ <td>@(room.PowerLevels.UserHasStatePermission(hs.UserId, RoomServerAclEventContent.EventId) ? "X" : "")</td>
<td>@room.Room.RoomId</td>
<td>@room.RoomName</td>
</tr>
@@ -58,7 +59,7 @@
private AuthenticatedHomeserverGeneric hs { get; set; }
protected override async Task OnInitializedAsync() {
- hs = await RMUStorage.GetCurrentSessionOrNavigate();
+ hs = await RmuStorage.GetCurrentSessionOrNavigate();
if (hs is null) return;
data = await hs.GetAccountDataAsync<DraupnirProtectedRoomsData>("org.matrix.mjolnir.protected_rooms");
StateHasChanged();
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/FindUsersByRegex.razor b/MatrixUtils.Web/Pages/Tools/Moderation/FindUsersByRegex.razor
index 2d78f4e..24bc6e1 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/FindUsersByRegex.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/FindUsersByRegex.razor
@@ -6,9 +6,9 @@
@using System.Text.RegularExpressions
@using LibMatrix
@using LibMatrix.EventTypes.Spec.State
+@using LibMatrix.EventTypes.Spec.State.RoomInfo
@using LibMatrix.Filters
@using LibMatrix.Helpers
-@using LibMatrix.Utilities
<h3>Find users by regex</h3>
<hr/>
@@ -64,7 +64,7 @@
protected override async Task OnInitializedAsync() {
log.CollectionChanged += (sender, args) => StateHasChanged();
log.Add("Authenticating");
- hs = await RMUStorage.GetCurrentSessionOrNavigate();
+ hs = await RmuStorage.GetCurrentSessionOrNavigate();
if (hs is null) return;
StateHasChanged();
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/InviteCounter.razor b/MatrixUtils.Web/Pages/Tools/Moderation/InviteCounter.razor
index 2123d4d..e7c5a7f 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/InviteCounter.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/InviteCounter.razor
@@ -1,6 +1,7 @@
@page "/Tools/Moderation/InviteCounter"
@using System.Collections.ObjectModel
@using LibMatrix.EventTypes.Spec.State
+@using LibMatrix.EventTypes.Spec.State.RoomInfo
<h3>Invite counter</h3>
<hr/>
@@ -34,7 +35,7 @@
protected override async Task OnInitializedAsync() {
log.CollectionChanged += (sender, args) => StateHasChanged();
- hs = await RMUStorage.GetCurrentSessionOrNavigate();
+ hs = await RmuStorage.GetCurrentSessionOrNavigate();
if (hs is null) return;
StateHasChanged();
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/MassCMEBan.razor b/MatrixUtils.Web/Pages/Tools/Moderation/MassCMEBan.razor
index a4e3918..b5e5edb 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/MassCMEBan.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/MassCMEBan.razor
@@ -28,7 +28,7 @@
protected override async Task OnInitializedAsync() {
log.CollectionChanged += (sender, args) => StateHasChanged();
- hs = await RMUStorage.GetCurrentSessionOrNavigate();
+ hs = await RmuStorage.GetCurrentSessionOrNavigate();
if (hs is null) return;
StateHasChanged();
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/MembershipHistory.razor b/MatrixUtils.Web/Pages/Tools/Moderation/MembershipHistory.razor
index 94afc9a..82ae072 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/MembershipHistory.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/MembershipHistory.razor
@@ -2,6 +2,7 @@
@using System.Collections.ObjectModel
@using LibMatrix
@using LibMatrix.EventTypes.Spec.State
+@using LibMatrix.EventTypes.Spec.State.RoomInfo
<h3>Membership history viewer</h3>
<hr/>
@@ -155,7 +156,7 @@
#region Filter bindings
- private bool _chronologicalOrder = false;
+ private bool _chronologicalOrder;
private bool ChronologicalOrder {
get => _chronologicalOrder;
@@ -266,7 +267,7 @@
protected override async Task OnInitializedAsync() {
log.CollectionChanged += (sender, args) => StateHasChanged();
- hs = await RMUStorage.GetCurrentSessionOrNavigate();
+ hs = await RmuStorage.GetCurrentSessionOrNavigate();
if (hs is null) return;
StateHasChanged();
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/RoomIntersections.razor b/MatrixUtils.Web/Pages/Tools/Moderation/RoomIntersections.razor
index b8baeb8..8516ea8 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/RoomIntersections.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/RoomIntersections.razor
@@ -3,6 +3,7 @@
@using System.Collections.ObjectModel
@using LibMatrix
@using LibMatrix.EventTypes.Spec.State
+@using LibMatrix.EventTypes.Spec.State.RoomInfo
<h3>Room intersections</h3>
<hr/>
@@ -113,7 +114,7 @@
protected override async Task OnInitializedAsync() {
Log.CollectionChanged += (sender, args) => StateHasChanged();
- hs = await RMUStorage.GetCurrentSessionOrNavigate();
+ hs = await RmuStorage.GetCurrentSessionOrNavigate();
if (hs is null) return;
StateHasChanged();
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/UserTrace.razor b/MatrixUtils.Web/Pages/Tools/Moderation/UserTrace.razor
index 915f8dc..3768da4 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/UserTrace.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/UserTrace.razor
@@ -3,13 +3,16 @@
@using LibMatrix.RoomTypes
@using System.Collections.ObjectModel
@using LibMatrix
+@using LibMatrix.EventTypes.Spec.State
+@using LibMatrix.EventTypes.Spec.State.RoomInfo
<h3>User Trace</h3>
<hr/>
<p>Users: </p>
<InputTextArea @bind-Value="@UserIdString"></InputTextArea>
<br/>
-<InputText @bind-Value="@ImportFromRoomId"></InputText><LinkButton OnClick="@DoImportFromRoomId">Import from room (ID)</LinkButton>
+<InputText @bind-Value="@ImportFromRoomId"></InputText>
+<LinkButton OnClick="@DoImportFromRoomId">Import from room (ID)</LinkButton>
<details>
<summary>Rooms to be searched (@rooms.Count)</summary>
@@ -24,18 +27,21 @@
<details>
<summary>Results</summary>
- @foreach (var (userId, events) in matches) {
+ @foreach (var (userId, events) in matches.OrderBy(x=>x.Key)) {
<h4>@userId</h4>
- <ul>
- @foreach (var match in events) {
- <li>
- <ul>
- <li>@match.RoomName (<span>@match.Room.RoomId</span>)</li>
- <li>Membership: @(match.Event.RawContent.ToJson(indent: false))</li>
- </ul>
- </li>
+ <table>
+ @foreach (var match in events.OrderBy(x=>x.RoomName)) {
+ <tr>
+ <td>@match.RoomName (<span>@match.Room.RoomId</span>)</td>
+ <td>
+ <details>
+ <summary>@SummarizeMembership(match.Event)</summary>
+ <pre>@match.Event.RawContent.ToJson(indent: true)</pre>
+ </details>
+ </td>
+ </tr>
}
- </ul>
+ </table>
}
</details>
@@ -61,56 +67,34 @@
protected override async Task OnInitializedAsync() {
log.CollectionChanged += (sender, args) => StateHasChanged();
- var hs = await RMUStorage.GetCurrentSessionOrNavigate();
+ var hs = await RmuStorage.GetCurrentSessionOrNavigate();
if (hs is null) return;
- // var sessions = await RMUStorage.GetAllTokens();
- // var baseRooms = new List<GenericRoom>();
- // foreach (var userAuth in sessions) {
- // var session = await RMUStorage.GetSession(userAuth);
- // if (session is not null) {
- // baseRooms.AddRange(await session.GetJoinedRooms());
- // var sessionRooms = (await session.GetJoinedRooms()).Where(x => !rooms.Any(y => y.Room.RoomId == x.RoomId)).ToList();
- // StateHasChanged();
- // log.Add($"Got {sessionRooms.Count} rooms for {userAuth.UserId}");
- // }
- // }
- //
- // log.Add("Done fetching rooms!");
- //
- // baseRooms = baseRooms.DistinctBy(x => x.RoomId).ToList();
- //
- // // rooms.CollectionChanged += (sender, args) => StateHasChanged();
- // var tasks = baseRooms.Select(async newRoom => {
- // bool success = false;
- // while (!success)
- // try {
- // var state = await newRoom.GetFullStateAsListAsync();
- // var newRoomInfo = new RoomInfo(newRoom, state);
- // rooms.Add(newRoomInfo);
- // log.Add($"Got {newRoomInfo.StateEvents.Count} events for {newRoomInfo.RoomName}");
- // success = true;
- // }
- // catch (MatrixException e) {
- // log.Add($"Failed to fetch room {newRoom.RoomId}! {e}");
- // throw;
- // }
- // catch (HttpRequestException e) {
- // log.Add($"Failed to fetch room {newRoom.RoomId}! {e}");
- // }
- // });
- // await Task.WhenAll(tasks);
- //
- // log.Add($"Done fetching members!");
- //
- // UserIDs.RemoveAll(x => sessions.Any(y => y.UserId == x));
-
- foreach (var session in await RMUStorage.GetAllTokens()) {
- var _hs = await RMUStorage.GetSession(session);
- if (_hs is not null) {
- rooms.AddRange(await _hs.GetJoinedRooms());
- log.Add($"Got {rooms.Count} rooms after adding {_hs.UserId}");
+
+ var sessions = await RmuStorage.GetAllTokens();
+ var tasks = sessions.Select(async session => {
+ try {
+ var _hs = await RmuStorage.GetSession(session);
+ if (_hs is not null) {
+ try {
+ var _rooms = await _hs.GetJoinedRooms();
+ if (!_rooms.Any()) return;
+ // Check if homeserver supports `?format=event`:
+ await _rooms.First().GetStateEventAsync(RoomMemberEventContent.EventId, session.UserId);
+ rooms.AddRange(_rooms);
+ log.Add($"Got {_rooms.Count} rooms for {_hs.UserId}, total {rooms.Count}");
+ }
+ catch (Exception e) {
+ if (e is LibMatrixException { ErrorCode: LibMatrixException.ErrorCodes.M_UNSUPPORTED })
+ log.Add($"Homeserver {_hs.UserId} does not support `?format=event`! Skipping...");
+ else log.Add($"Failed to fetch rooms for {_hs.UserId}! {e}");
+ }
+ }
}
- }
+ catch (Exception e) {
+ log.Add($"Failed to fetch rooms for {session.UserId}! {e}");
+ }
+ });
+ await Task.WhenAll(tasks);
//get distinct rooms evenly distributed per session, accounting for count per session
rooms = rooms.OrderBy(x => rooms.Count(y => y.Homeserver == x.Homeserver)).DistinctBy(x => x.RoomId).ToList();
@@ -125,17 +109,6 @@
foreach (var userId in UserIDs) {
matches.Add(userId, new List<Match>());
- // foreach (var room in rooms) {
- // var state = room.StateEvents.Where(x => x!.Type == RoomMemberEventContent.EventId).ToList();
- // if (state!.Any(x => x.StateKey == userId)) {
- // matches[userId].Add(new() {
- // Event = state.First(x => x.StateKey == userId),
- // Room = room.Room,
- // RoomName = room.RoomName ?? "No name"
- // });
- // }
- // }
-
log.Add($"Searching for {userId}...");
await foreach (var match in GetMatches(userId)) {
matches[userId].Add(match);
@@ -173,13 +146,19 @@
private async IAsyncEnumerable<Match> GetMatches(string userId) {
var results = rooms.Select(async room => {
- var state = await room.GetStateEventOrNullAsync(room.RoomId, userId);
- if (state is not null) {
- return new Match {
- Room = room,
- Event = state,
- RoomName = await room.GetNameOrFallbackAsync()
- };
+ try {
+ var state = await room.GetStateEventOrNullAsync(RoomMemberEventContent.EventId, userId);
+ if (state is not null) {
+ log.Add($"Found {userId} in {room.RoomId} with membership {state.RawContent.ToJson(indent: false)}");
+ return new Match {
+ Room = room,
+ Event = state,
+ RoomName = await room.GetNameOrFallbackAsync()
+ };
+ }
+ }
+ catch (Exception e) {
+ log.Add($"Failed to fetch state for {userId} in {room.RoomId}! {e}");
}
return null;
@@ -191,4 +170,19 @@
}
}
+ public string SummarizeMembership(StateEventResponse state) {
+ var membership = state.ContentAs<RoomMemberEventContent>();
+ var time = DateTimeOffset.FromUnixTimeMilliseconds(state.OriginServerTs!.Value);
+ return membership switch {
+ { Membership: "invite", Reason: null } => $"Invited by {state.Sender} at {time}",
+ { Membership: "invite", Reason: not null } => $"Invited by {state.Sender} at {time} for {membership.Reason}",
+ { Membership: "join", Reason: null } => $"Joined at {time}",
+ { Membership: "join", Reason: not null } => $"Joined at {time} for {membership.Reason}",
+ { Membership: "leave", Reason: null } => state.Sender == state.StateKey ? $"Left at {time}" : $"Kicked by {state.Sender} at {time}",
+ { Membership: "leave", Reason: not null } => state.Sender == state.StateKey ? $"Left at {time} with reason {membership.Reason}" : $"Kicked by {state.Sender} at {time} for {membership.Reason}",
+ { Membership: "ban", Reason: null } => $"Banned by {state.Sender} at {time}",
+ { Membership: "ban", Reason: not null } => $"Banned by {state.Sender} at {time} for {membership.Reason}",
+ };
+ }
+
}
\ No newline at end of file
|