about summary refs log tree commit diff
path: root/MatrixRoomUtils.Web/Pages/Rooms
diff options
context:
space:
mode:
authorTheArcaneBrony <myrainbowdash949@gmail.com>2023-07-02 01:01:09 +0200
committerTheArcaneBrony <myrainbowdash949@gmail.com>2023-07-02 01:01:09 +0200
commitdef33cc092ae2c6defcc218b108b7c99cbfb8581 (patch)
treeba992ff8c30b7d4e8af0a78350e157e095455a18 /MatrixRoomUtils.Web/Pages/Rooms
parentDeduplicate some api calls (diff)
downloadMatrixUtils-def33cc092ae2c6defcc218b108b7c99cbfb8581.tar.xz
Prefetch room info
Diffstat (limited to 'MatrixRoomUtils.Web/Pages/Rooms')
-rw-r--r--MatrixRoomUtils.Web/Pages/Rooms/Index.razor9
-rw-r--r--MatrixRoomUtils.Web/Pages/Rooms/PolicyList.razor250
2 files changed, 255 insertions, 4 deletions
diff --git a/MatrixRoomUtils.Web/Pages/Rooms/Index.razor b/MatrixRoomUtils.Web/Pages/Rooms/Index.razor

index 932748d..d88d5b2 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/Index.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/Index.razor
@@ -1,5 +1,6 @@ @page "/Rooms" @using MatrixRoomUtils.Core.StateEventTypes +@using MatrixRoomUtils.Core.StateEventTypes.Spec <h3>Room list</h3> @if (Rooms is not null) { @@ -9,14 +10,14 @@ @code { - private List<GenericRoom> Rooms { get; set; } - private ProfileResponse GlobalProfile { get; set; } - + private List<RoomInfo> Rooms { get; set; } + private ProfileResponseEventData GlobalProfile { get; set; } + protected override async Task OnInitializedAsync() { var hs = await MRUStorage.GetCurrentSessionOrNavigate(); if (hs is null) return; GlobalProfile = await hs.GetProfile(hs.WhoAmI.UserId); - Rooms = await hs.GetJoinedRooms(); + Rooms = (await hs.GetJoinedRooms()).Select(x => new RoomInfo() { Room = x }).ToList(); await base.OnInitializedAsync(); } diff --git a/MatrixRoomUtils.Web/Pages/Rooms/PolicyList.razor b/MatrixRoomUtils.Web/Pages/Rooms/PolicyList.razor new file mode 100644
index 0000000..4cb16b8 --- /dev/null +++ b/MatrixRoomUtils.Web/Pages/Rooms/PolicyList.razor
@@ -0,0 +1,250 @@ +@page "/Rooms/{RoomId}/Policies" +@using MatrixRoomUtils.Core.StateEventTypes +@using System.Text.Json +@using MatrixRoomUtils.Core.Helpers +@using MatrixRoomUtils.Core.Responses +@using MatrixRoomUtils.Core.StateEventTypes.Spec +<h3>Policy list editor - Editing @RoomId</h3> +<hr/> + +<p> + This policy list contains @PolicyEvents.Count(x => x.Type == "m.policy.rule.server") server bans, + @PolicyEvents.Count(x => x.Type == "m.policy.rule.room") room bans and + @PolicyEvents.Count(x => x.Type == "m.policy.rule.user") user bans. +</p> +<InputCheckbox @bind-Value="_enableAvatars" @oninput="GetAllAvatars"></InputCheckbox><label>Enable avatars (WILL EXPOSE YOUR IP TO TARGET HOMESERVERS!)</label> + + +@if (!PolicyEvents.Any(x => x.Type == "m.policy.rule.server")) { + <p>No server policies</p> +} +else { + <h3>Server policies</h3> + <hr/> + <table class="table table-striped table-hover" style="width: fit-Content;"> + <thead> + <tr> + <th scope="col" style="max-width: 50vw;">Server</th> + <th scope="col">Reason</th> + <th scope="col">Expires</th> + <th scope="col">Actions</th> + </tr> + </thead> + <tbody> + @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.server" && (x.TypedContent as PolicyRuleStateEventData).Entity is not null)) { + var policyData = policyEvent.TypedContent as PolicyRuleStateEventData; + <tr> + <td>Entity: @policyData.Entity<br/>State: @policyEvent.StateKey</td> + <td>@policyData.Reason</td> + <td> + @policyData.ExpiryDateTime + </td> + <td> + <button class="btn" @* @onclick="async () => await RemovePolicyAsync(policyEvent)" *@>Edit</button> + @* <button class="btn btn-danger" $1$ @onclick="async () => await RemovePolicyAsync(policyEvent)" #1#>Remove</button> *@ + </td> + </tr> + } + </tbody> + </table> + <details> + <summary>Redacted events</summary> + <table class="table table-striped table-hover" style="width: fit-Content;"> + <thead> + <tr> + <th scope="col" style="max-width: 50vw;">State key</th> + <th scope="col">Serialised Contents</th> + </tr> + </thead> + <tbody> + @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.server" && (x.TypedContent as PolicyRuleStateEventData).Entity == null)) { + var policyData = policyEvent.TypedContent as PolicyRuleStateEventData; + <tr> + <td>@policyEvent.StateKey</td> + <td>@policyEvent.RawContent.ToJson(false, true)</td> + </tr> + } + </tbody> + </table> + </details> +} +@if (!PolicyEvents.Any(x => x.Type == "m.policy.rule.room")) { + <p>No room policies</p> +} +else { + <h3>Room policies</h3> + <hr/> + <table class="table table-striped table-hover" style="width: fit-Content;"> + <thead> + <tr> + <th scope="col" style="max-width: 50vw;">Room</th> + <th scope="col">Reason</th> + <th scope="col">Expires</th> + <th scope="col">Actions</th> + </tr> + </thead> + <tbody> + @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.room" && (x.TypedContent as PolicyRuleStateEventData).Entity is not null)) { + var policyData = policyEvent.TypedContent as PolicyRuleStateEventData; + <tr> + <td>Entity: @policyData.Entity<br/>State: @policyEvent.StateKey</td> + <td>@policyData.Reason</td> + <td> + @policyData.ExpiryDateTime + </td> + <td> + <button class="btn btn-danger" @* @onclick="async () => await RemovePolicyAsync(policyEvent)" *@>Remove</button> + </td> + </tr> + } + </tbody> + </table> + <details> + <summary>Redacted events</summary> + <table class="table table-striped table-hover" style="width: fit-Content;"> + <thead> + <tr> + <th scope="col" style="max-width: 50vw;">State key</th> + <th scope="col">Serialised Contents</th> + </tr> + </thead> + <tbody> + @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.room" && (x.TypedContent as PolicyRuleStateEventData).Entity == null)) { + <tr> + <td>@policyEvent.StateKey</td> + <td>@policyEvent.RawContent.ToJson(false, true)</td> + </tr> + } + </tbody> + </table> + </details> +} +@if (!PolicyEvents.Any(x => x.Type == "m.policy.rule.user")) { + <p>No user policies</p> +} +else { + <h3>User policies</h3> + <hr/> + <table class="table table-striped table-hover" style="width: fit-Content;"> + <thead> + <tr> + @if (_enableAvatars) { + <th scope="col"></th> + } + <th scope="col" style="max-width: 0.2vw; word-wrap: anywhere;">User</th> + <th scope="col">Reason</th> + <th scope="col">Expires</th> + <th scope="col">Actions</th> + </tr> + </thead> + <tbody> + @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.user" && (x.TypedContent as PolicyRuleStateEventData).Entity is not null)) { + var policyData = policyEvent.TypedContent as PolicyRuleStateEventData; + <tr> + @if (_enableAvatars) { + <td scope="col"> + <img style="width: 48px; height: 48px; aspect-ratio: unset; border-radius: 50%;" src="@(avatars.ContainsKey(policyData.Entity) ? avatars[policyData.Entity] : "")"/> + </td> + } + <td style="word-wrap: anywhere;">Entity: @string.Join("", policyData.Entity.Take(64))<br/>State: @string.Join("", policyEvent.StateKey.Take(64))</td> + <td>@policyData.Reason</td> + <td> + @policyData.ExpiryDateTime + </td> + <td> + <button class="btn btn-danger" @* @onclick="async () => await RemovePolicyAsync(policyEvent)" *@>Remove</button> + </td> + </tr> + } + </tbody> + </table> + <details> + <summary>Redacted events</summary> + <table class="table table-striped table-hover" style="width: fit-Content;"> + <thead> + <tr> + <th scope="col">State key</th> + <th scope="col">Serialised Contents</th> + </tr> + </thead> + <tbody> + @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.user" && (x.TypedContent as PolicyRuleStateEventData).Entity == null)) { + <tr> + <td>@policyEvent.StateKey</td> + <td>@policyEvent.RawContent.ToJson(false, true)</td> + </tr> + } + </tbody> + </table> + </details> +} + +<LogView></LogView> + +@code { + //get room list + // - sync withroom list filter + // Type = support.feline.msc3784 + //support.feline.policy.lists.msc.v1 + + [Parameter] + public string? RoomId { get; set; } + + private bool _enableAvatars; + + static readonly Dictionary<string, string?> avatars = new(); + static readonly Dictionary<string, RemoteHomeServer> servers = new(); + + public static List<StateEventResponse> PolicyEvents { get; set; } = new(); + + protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + var hs = await MRUStorage.GetCurrentSessionOrNavigate(); + if (hs is null) return; + RoomId = RoomId.Replace('~', '.'); + await LoadStatesAsync(); + Console.WriteLine("Policy list editor initialized!"); + } + + private async Task LoadStatesAsync() { + var hs = await MRUStorage.GetCurrentSession(); + var room = await hs.GetRoom(RoomId); + + var states = room.GetFullStateAsync(); + await foreach (var state in states) { + if (!state.Type.StartsWith("m.policy.rule")) continue; + PolicyEvents.Add(state); + } + + + // var stateEventsQuery = await room.GetStateAsync(""); + // var stateEvents = stateEventsQuery.Value.Deserialize<List<StateEventResponse>>(); + // PolicyEvents = stateEvents.Where(x => x.Type.StartsWith("m.policy.rule")) + // .Select(x => JsonSerializer.Deserialize<StateEventResponse>(JsonSerializer.Serialize(x))).ToList(); + StateHasChanged(); + } + + private async Task GetAvatar(string userId) { + try { + if (avatars.ContainsKey(userId)) return; + var hs = userId.Split(':')[1]; + var server = servers.ContainsKey(hs) ? servers[hs] : new RemoteHomeServer(userId.Split(':')[1]); + if (!servers.ContainsKey(hs)) servers.Add(hs, server); + var profile = await server.GetProfile(userId); + avatars.Add(userId, MediaResolver.ResolveMediaUri(server.FullHomeServerDomain, profile.AvatarUrl)); + servers.Add(userId, server); + StateHasChanged(); + } + catch { + // ignored + } + } + + private async Task GetAllAvatars() { + foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.user" && (x.TypedContent as PolicyRuleStateEventData).Entity is not null)) { + await GetAvatar((policyEvent.TypedContent as PolicyRuleStateEventData).Entity); + } + StateHasChanged(); + } + +} \ No newline at end of file