@page "/HSAdmin/Synapse/RoomQuery" @using Microsoft.AspNetCore.WebUtilities @using ArcaneLibs.Extensions @using LibMatrix.Homeservers.ImplementationDetails.Synapse.Models.Filters @using LibMatrix.Homeservers.ImplementationDetails.Synapse.Models.Requests @using LibMatrix.Homeservers.ImplementationDetails.Synapse.Models.Responses @using MatrixUtils.Web.Pages.HSAdmin.Synapse.Components

Homeserver Administration - Room Query




Local filtering (slow)
String contains Room ID: Room name: Canonical alias: Creator: Room version: Encryption algorithm: Join rules: Guest access: History visibility: Optional checks Is federated: @if (Filter.CheckFederation) { } Is public: @if (Filter.CheckPublic) { } Ranges state events members local members

@if (Results.Count > 0) {

Found @Results.Count rooms

TSV data (copy/paste)
            
                @foreach (var res in Results) {
                    
                }
            
@res.RoomId@("\t") @res.CanonicalAlias@("\t") @res.Creator@("\t") @res.Name
} @foreach (var res in Results) {
@* *@

@if (!string.IsNullOrWhiteSpace(res.CanonicalAlias)) { @res.CanonicalAlias - @res.RoomId (@res.Name)
} else { @res.RoomId (@res.Name)
} @if (!string.IsNullOrWhiteSpace(res.Creator)) { @* Created by *@ Created by @res.Creator
}

Delete room

@res.StateEvents state events
@if (res.LocalMembers is null) { @res.JoinedMembers members, of which @res.JoinedLocalMembers are on this server } else { @res.JoinedMembers members, of which @res.JoinedLocalMembers are on this server: @(string.Join(", ", res.LocalMembers)) }
Full result data
@res.ToJson(ignoreNull: true)
} @* *@ @* @if (DeleteRequest.HasValue) { *@ @* *@ @* *@ @* *@ @* } *@ @* @foreach (var (roomId, status) in DeleteStatuses) { *@ @* *@ @*
@status.ToJson()
*@ @*
*@ @* } *@ @foreach(var (roomId, deleteRequest) in DeleteRequests) { } @code { [Parameter] [SupplyParameterFromQuery(Name = "order_by")] public string? OrderBy { get; set; } [Parameter] [SupplyParameterFromQuery(Name = "name_search")] public string SearchTerm { get; set; } [Parameter] [SupplyParameterFromQuery(Name = "ascending")] public bool Ascending { get; set; } private List Results { get; set; } = new(); private AuthenticatedHomeserverSynapse Homeserver { get; set; } = null!; private string Status { get; set; } public SynapseAdminLocalRoomQueryFilter Filter { get; set; } = new(); private Dictionary DeleteRequests { get; set; } = []; // private Dictionary DeleteStatuses { get; set; } = new(); protected override Task OnParametersSetAsync() { if (Ascending == null) Ascending = true; OrderBy ??= "name"; var execute = false; foreach (var (key, value) in QueryHelpers.ParseQuery(new Uri(NavigationManager.Uri).Query)) { switch (key) { case "RoomIdContains": Filter.RoomIdContains = value[0]!; break; case "NameContains": Filter.NameContains = value[0]!; break; case "CanonicalAliasContains": Filter.CanonicalAliasContains = value[0]!; break; case "VersionContains": Filter.VersionContains = value[0]!; break; case "CreatorContains": Filter.CreatorContains = value[0]!; break; case "EncryptionContains": Filter.EncryptionContains = value[0]!; break; case "JoinRulesContains": Filter.JoinRulesContains = value[0]!; break; case "GuestAccessContains": Filter.GuestAccessContains = value[0]!; break; case "HistoryVisibilityContains": Filter.HistoryVisibilityContains = value[0]!; break; case "Federatable": Filter.Federatable = bool.Parse(value[0]!); Filter.CheckFederation = true; break; case "Public": Filter.Public = value[0] == "true"; Filter.CheckPublic = true; break; case "JoinedMembersGreaterThan": Filter.JoinedMembersGreaterThan = int.Parse(value[0]!); break; case "JoinedMembersLessThan": Filter.JoinedMembersLessThan = int.Parse(value[0]!); break; case "JoinedLocalMembersGreaterThan": Filter.JoinedLocalMembersGreaterThan = int.Parse(value[0]!); break; case "JoinedLocalMembersLessThan": Filter.JoinedLocalMembersLessThan = int.Parse(value[0]!); break; case "StateEventsGreaterThan": Filter.StateEventsGreaterThan = int.Parse(value[0]!); break; case "StateEventsLessThan": Filter.StateEventsLessThan = int.Parse(value[0]!); break; case "Execute": execute = true; break; default: Console.WriteLine($"Unknown query parameter: {key}"); break; } } if (execute) _ = Search(); return Task.CompletedTask; } private async Task Search() { Results.Clear(); var hs = await sessionStore.GetCurrentHomeserver(navigateOnFailure: true); if (hs is AuthenticatedHomeserverSynapse synapse) { Homeserver = synapse; var searchRooms = synapse.Admin.SearchRoomsAsync(orderBy: OrderBy!, dir: Ascending ? "f" : "b", searchTerm: SearchTerm, localFilter: Filter).GetAsyncEnumerator(); while (await searchRooms.MoveNextAsync()) { var room = searchRooms.Current; if (Results.Count < 100) Console.WriteLine("Hit: " + room.ToJson(false)); var roomInfo = new RoomInfo { RoomId = room.RoomId, Name = room.Name, CanonicalAlias = room.CanonicalAlias, Creator = room.Creator, Version = room.Version, Encryption = room.Encryption, Federatable = room.Federatable, Public = room.Public, JoinRules = room.JoinRules, GuestAccess = room.GuestAccess, HistoryVisibility = room.HistoryVisibility, StateEvents = room.StateEvents, JoinedMembers = room.JoinedMembers, JoinedLocalMembers = room.JoinedLocalMembers }; Results.Add(roomInfo); if (room.JoinedLocalMembers is > 0 and < 100) roomInfo.LocalMembers = (await synapse.Admin.GetRoomMembersAsync(room.RoomId)).Members.Where(x => x.EndsWith(":" + synapse.ServerName)).ToList(); if (Results.Count < 200 || Results.Count % 1000 == 0) { StateHasChanged(); await Task.Yield(); } } } StateHasChanged(); } // // private async Task DeleteRoom() { // if (DeleteRequest is { } deleteRequest) { // var media = await Homeserver.Admin.GetRoomMediaAsync(deleteRequest.RoomId); // if (deleteRequest.DeleteRequest.QuarantineRemoteMedia) { // foreach (var remoteMedia in media.Remote) { // await Homeserver.Admin.QuarantineMediaById(remoteMedia); // } // } // // if (deleteRequest.DeleteRequest.DeleteRemoteMedia) { // foreach (var remoteMedia in media.Remote) { // await Homeserver.Admin.DeleteMediaById(remoteMedia); // } // } // else if (deleteRequest.DeleteRequest.QuarantineLocalMedia) { // foreach (var localMedia in media.Local) { // await Homeserver.Admin.QuarantineMediaById(localMedia); // } // } // // var deleteId = await Homeserver.Admin.DeleteRoom(deleteRequest.RoomId, deleteRequest.DeleteRequest, waitForCompletion: false); // DeleteRequest = null; // List alreadyCleanedUsers = []; // while (true) { // var status = await Homeserver.Admin.GetRoomDeleteStatus(deleteId.DeleteId); // DeleteStatuses[deleteRequest.RoomId] = status; // StateHasChanged(); // await Task.Delay(5000); // if (status.Status == "complete") { // DeleteStatuses.Remove(deleteRequest.RoomId); // StateHasChanged(); // break; // } // // if (status.Status == "failed") { // deleteId = await Homeserver.Admin.DeleteRoom(deleteRequest.RoomId, deleteRequest.DeleteRequest, waitForCompletion: false); // } // // var newCleanedUsers = status.ShutdownRoom?.KickedUsers?.Except(alreadyCleanedUsers).ToList(); // if (newCleanedUsers is not null) { // alreadyCleanedUsers.AddRange(newCleanedUsers); // foreach (var user in newCleanedUsers) { // if (deleteRequest.DeleteRequest.SuspendLocalUsers) { // // await Homeserver.Admin.(user); // } // // if (deleteRequest.DeleteRequest.QuarantineLocalUserMedia) { // await Homeserver.Admin.QuarantineMediaByUserId(user); // } // // if (deleteRequest.DeleteRequest.DeleteLocalUserMedia) { // var userMedia = Homeserver.Admin.GetUserMediaEnumerableAsync(user); // await foreach (var mediaEntry in userMedia) { // await Homeserver.Admin.DeleteMediaById(mediaEntry.MediaId); // } // } // } // } // } // } // } private readonly Dictionary validOrderBy = new() { { "name", "Room name" }, { "canonical_alias", "Main alias address" }, { "joined_members", "Number of members (reversed)" }, { "joined_local_members", "Number of local members (reversed)" }, { "version", "Room version" }, { "creator", "Creator of the room" }, { "encryption", "End-to-end encryption algorithm" }, { "federatable", "Is room federated" }, { "public", "Visibility in room list" }, { "join_rules", "Join rules" }, { "guest_access", "Guest access" }, { "history_visibility", "Visibility of history" }, { "state_events", "Number of state events" } }; private class RoomInfo : SynapseAdminRoomListResult.SynapseAdminRoomListResultRoom { public List? LocalMembers { get; set; } } }