about summary refs log tree commit diff
path: root/MatrixUtils.Web/Pages/Index.razor
diff options
context:
space:
mode:
Diffstat (limited to 'MatrixUtils.Web/Pages/Index.razor')
-rw-r--r--MatrixUtils.Web/Pages/Index.razor191
1 files changed, 191 insertions, 0 deletions
diff --git a/MatrixUtils.Web/Pages/Index.razor b/MatrixUtils.Web/Pages/Index.razor
new file mode 100644
index 0000000..9c1bab6
--- /dev/null
+++ b/MatrixUtils.Web/Pages/Index.razor
@@ -0,0 +1,191 @@
+@page "/"
+@inject ILogger<Index> logger
+@using LibMatrix.Responses
+@using LibMatrix
+@using LibMatrix.Homeservers
+@using ArcaneLibs.Extensions
+@using MatrixUtils.Web.Pages.Dev
+
+<PageTitle>Index</PageTitle>
+
+<h3>Rory&::MatrixUtils</h3>
+Small collection of tools to do not-so-everyday things.
+
+<br/><br/>
+<h5>Signed in accounts - <a href="/Login">Add new account</a></h5>
+<hr/>
+<form>
+    <table>
+        @foreach (var session in _sessions.OrderByDescending(x => x.UserInfo.RoomCount)) {
+            var _auth = session.UserAuth;
+            <tr class="user-entry">
+                <td>
+                    <img class="avatar" src="@session.UserInfo.AvatarUrl"/>
+                </td>
+                <td class="user-info">
+                    <p>
+                        <input type="radio" name="csa" checked="@(_currentSession.AccessToken == _auth.AccessToken)" @onclick="@(() => SwitchSession(_auth))" style="text-decoration-line: unset;"/>
+                        <b>@session.UserInfo.DisplayName</b> on <b>@_auth.Homeserver</b><br/>
+                    </p>
+                    <span style="display: inline-block; width: 128px;">@session.UserInfo.RoomCount rooms</span>
+                    <a style="color: #888888" href="@("/ServerInfo/" + session.Homeserver.ServerName + "/")">@session.ServerVersion.Server.Name @session.ServerVersion.Server.Version</a>
+                    @if (_auth.Proxy != null) {
+                        <span class="badge badge-info"> (proxied via @_auth.Proxy)</span>
+                    }
+                    else {
+                        <p>Not proxied</p>
+                    }
+                    @if (_debug) {
+                        <p>T=@session.Homeserver.GetType().FullName</p>
+                        <p>D=@session.Homeserver.WhoAmI.DeviceId</p>
+                        <p>U=@session.Homeserver.WhoAmI.UserId</p>
+                    }
+                </td>
+                <td>
+                    <p>
+                        <LinkButton OnClick="@(() => ManageUser(_auth))">Manage</LinkButton>
+                        <LinkButton OnClick="@(() => RemoveUser(_auth))">Remove</LinkButton>
+                        <LinkButton OnClick="@(() => RemoveUser(_auth, true))">Log out</LinkButton>
+                    </p>
+                </td>
+            </tr>
+        }
+    </table>
+</form>
+
+@if (_offlineSessions.Count > 0) {
+    <br/>
+    <br/>
+    <h5>Sessions on unreachable servers</h5>
+    <hr/>
+    <form>
+        <table>
+            @foreach (var session in _offlineSessions) {
+                <tr class="user-entry">
+                    <td>
+                        <p>
+                            @{
+                                string[] parts = session.UserId.Split(':');
+                            }
+                            <span>@parts[0][1..]</span> on <span>@parts[1]</span>
+                            @if (!string.IsNullOrWhiteSpace(session.Proxy)) {
+                                <span class="badge badge-info"> (proxied via @session.Proxy)</span>
+                            }
+                        </p>
+                    </td>
+                    <td>
+                        <LinkButton OnClick="@(() => RemoveUser(session))">Remove</LinkButton>
+                    </td>
+                </tr>
+            }
+        </table>
+    </form>
+}
+
+@code
+{
+#if DEBUG
+    private const bool _debug = true;
+#else
+    private const bool _debug = false;
+#endif
+
+    private class AuthInfo {
+        public UserAuth UserAuth { get; set; }
+        public UserInfo UserInfo { get; set; }
+        public ServerVersionResponse ServerVersion { get; set; }
+        public AuthenticatedHomeserverGeneric Homeserver { get; set; }
+    }
+
+    // private Dictionary<UserAuth, UserInfo> _users = new();
+    private readonly List<AuthInfo> _sessions = [];
+    private readonly List<UserAuth> _offlineSessions = [];
+    private LoginResponse? _currentSession;
+
+    protected override async Task OnInitializedAsync() {
+        Console.WriteLine("Index.OnInitializedAsync");
+        _currentSession = await RMUStorage.GetCurrentToken();
+        _sessions.Clear();
+        _offlineSessions.Clear();
+        var tokens = await RMUStorage.GetAllTokens();
+        var profileTasks = tokens.Select(async token => {
+            UserInfo userInfo = new();
+            AuthenticatedHomeserverGeneric hs;
+            Console.WriteLine($"Getting hs for {token.ToJson()}");
+            try {
+                hs = await hsProvider.GetAuthenticatedWithToken(token.Homeserver, token.AccessToken, token.Proxy);
+            }
+            catch (MatrixException e) {
+                if (e.ErrorCode != "M_UNKNOWN_TOKEN") throw;
+                NavigationManager.NavigateTo("/InvalidSession?ctx=" + token.AccessToken);
+                return;
+
+            }
+            catch (Exception e) {
+                logger.LogError(e, $"Failed to instantiate AuthenticatedHomeserver for {token.ToJson()}, homeserver may be offline?", token.UserId);
+                _offlineSessions.Add(token);
+                return;
+            }
+            
+            Console.WriteLine($"Got hs for {token.ToJson()}");
+
+            var roomCountTask = hs.GetJoinedRooms();
+            var profile = await hs.GetProfileAsync(hs.WhoAmI.UserId);
+            userInfo.DisplayName = profile.DisplayName ?? hs.WhoAmI.UserId;
+            Console.WriteLine(profile.ToJson());
+            _sessions.Add(new() {
+                UserInfo = new() {
+                    AvatarUrl = string.IsNullOrWhiteSpace(profile.AvatarUrl) ? "https://api.dicebear.com/6.x/identicon/svg?seed=" + hs.WhoAmI.UserId : hs.ResolveMediaUri(profile.AvatarUrl),
+                    RoomCount = (await roomCountTask).Count,
+                    DisplayName = profile.DisplayName ?? hs.WhoAmI.UserId
+                },
+                UserAuth = token,
+                ServerVersion = await (hs.FederationClient?.GetServerVersionAsync() ?? Task.FromResult<ServerVersionResponse?>(null)),
+                Homeserver = hs
+            });
+        });
+        Console.WriteLine("Waiting for profile tasks");
+        await Task.WhenAll(profileTasks);
+        Console.WriteLine("Done waiting for profile tasks");
+        await base.OnInitializedAsync();
+    }
+
+    private class UserInfo {
+        internal string AvatarUrl { get; set; }
+        internal string DisplayName { get; set; }
+        internal int RoomCount { get; set; }
+    }
+
+    private async Task RemoveUser(UserAuth auth, bool logout = false) {
+        try {
+            if (logout) {
+                await (await hsProvider.GetAuthenticatedWithToken(auth.Homeserver, auth.AccessToken, auth.Proxy)).Logout();
+            }
+        }
+        catch (Exception e) {
+            if (e is MatrixException { ErrorCode: "M_UNKNOWN_TOKEN" }) {
+                //todo: handle this
+                return;
+            }
+
+            Console.WriteLine(e);
+        }
+
+        await RMUStorage.RemoveToken(auth);
+        if ((await RMUStorage.GetCurrentToken())?.AccessToken == auth.AccessToken)
+            await RMUStorage.SetCurrentToken((await RMUStorage.GetAllTokens() ?? throw new InvalidOperationException()).FirstOrDefault());
+        await OnInitializedAsync();
+    }
+
+
+    private async Task SwitchSession(UserAuth auth) {
+        Console.WriteLine($"Switching to {auth.Homeserver} {auth.UserId} via {auth.Proxy}");
+        await RMUStorage.SetCurrentToken(auth);
+        await OnInitializedAsync();
+    }
+
+    private async Task ManageUser(UserAuth auth) {
+        await SwitchSession(auth);
+        NavigationManager.NavigateTo("/User/Profile");
+    }
+}
\ No newline at end of file