diff --git a/LibMatrix b/LibMatrix
-Subproject a481bead16d904da8ad4d6de8d1a8ab006460b3
+Subproject cb92b267f46113f3c0a6138729ac584be6ae939
diff --git a/MatrixRoomUtils.Web/Pages/About.razor b/MatrixRoomUtils.Web/Pages/About.razor
index a5864ab..59368af 100644
--- a/MatrixRoomUtils.Web/Pages/About.razor
+++ b/MatrixRoomUtils.Web/Pages/About.razor
@@ -7,29 +7,29 @@
<h3>Rory&::MatrixUtils - About</h3>
<hr/>
-<p>Rory&::MatrixRoomUtils is a "small" collection of tools to do not-so-everyday things.</p>
+<p>Rory&::MatrixUtils is a "small" collection of tools to do not-so-everyday things.</p>
<p>These range from joining rooms on dead homeservers, to managing your accounts and rooms, and creating rooms based on templates.</p>
<br/><br/>
-<p>You can find the source code on <a href="https://cgit.rory.gay/MatrixRoomUtils.git/">my git server</a>.<br/></p>
+<p>You can find the source code on <a href="https://cgit.rory.gay/matrix/MatrixRoomUtils.git/">cgit.rory.gay</a>.<br/></p>
<p>You can also join the <a href="https://matrix.to/#/%23mru%3Arory.gay?via=rory.gay&via=matrix.org&via=feline.support">Matrix room</a> for this project.</p>
-@if (ShowBinDownload) {
- <p>This deployment also serves a copy of the compiled, hosting-ready binaries at <a href="MRU-BIN.tar.xz">/MRU-BIN.tar.xz</a>!</p>
+@if (BinDownloadAvailable) {
+ <p>This deployment also serves a copy of the compiled, hosting-ready binaries at <a href="/MRU-BIN.tar.xz">/MRU-BIN.tar.xz</a>!</p>
}
-@if (ShowSrcDownload) {
- <p>This deployment also serves a copy of the compiled, hosting-ready binaries at <a href="MRU-SRC.tar.xz">/MRU-SRC.tar.xz</a>!</p>
+@if (SrcDownloadAvailable) {
+ <p>This deployment also serves a copy of the source code at <a href="/MRU-SRC.tar.xz">/MRU-SRC.tar.xz</a>!</p>
}
@code {
- private bool ShowBinDownload { get; set; }
- private bool ShowSrcDownload { get; set; }
+ private bool BinDownloadAvailable { get; set; }
+ private bool SrcDownloadAvailable { get; set; }
protected override async Task OnInitializedAsync() {
using var hc = new HttpClient();
var hr = await hc.SendAsync(new HttpRequestMessage(HttpMethod.Head, NavigationManager.ToAbsoluteUri("/MRU-BIN.tar.xz").AbsoluteUri));
- ShowBinDownload = hr.StatusCode == HttpStatusCode.OK;
+ BinDownloadAvailable = hr.StatusCode == HttpStatusCode.OK;
hr = await hc.SendAsync(new HttpRequestMessage(HttpMethod.Head, NavigationManager.ToAbsoluteUri("/MRU-SRC.tar.xz").AbsoluteUri));
- ShowSrcDownload = hr.StatusCode == HttpStatusCode.OK;
+ SrcDownloadAvailable = hr.StatusCode == HttpStatusCode.OK;
await base.OnInitializedAsync();
}
diff --git a/MatrixRoomUtils.Web/Pages/HSAdmin/HSAdmin.razor b/MatrixRoomUtils.Web/Pages/HSAdmin/HSAdmin.razor
index c605e7a..d1a2df5 100644
--- a/MatrixRoomUtils.Web/Pages/HSAdmin/HSAdmin.razor
+++ b/MatrixRoomUtils.Web/Pages/HSAdmin/HSAdmin.razor
@@ -27,7 +27,7 @@ else {
protected override async Task OnInitializedAsync() {
Homeserver = await MRUStorage.GetCurrentSessionOrNavigate();
if (Homeserver is null) return;
- ServerVersionResponse = await Homeserver.GetServerVersionAsync();
+ ServerVersionResponse = await (Homeserver.FederationClient?.GetServerVersionAsync() ?? Task.FromResult<ServerVersionResponse?>(null));
await base.OnInitializedAsync();
}
diff --git a/MatrixRoomUtils.Web/Pages/Index.razor b/MatrixRoomUtils.Web/Pages/Index.razor
index ebb0ebb..250dc2d 100644
--- a/MatrixRoomUtils.Web/Pages/Index.razor
+++ b/MatrixRoomUtils.Web/Pages/Index.razor
@@ -121,7 +121,7 @@ Small collection of tools to do not-so-everyday things.
return;
}
- catch (HttpRequestException e) {
+ catch (Exception e) {
logger.LogError(e, $"Failed to instantiate AuthenticatedHomeserver for {token.ToJson()}, homeserver may be offline?", token.UserId);
_offlineSessions.Add(token);
return;
@@ -140,7 +140,7 @@ Small collection of tools to do not-so-everyday things.
DisplayName = profile.DisplayName ?? hs.WhoAmI.UserId
},
UserAuth = token,
- ServerVersion = await hs.GetServerVersionAsync(),
+ ServerVersion = await (hs.FederationClient?.GetServerVersionAsync() ?? Task.FromResult<ServerVersionResponse?>(null)),
Homeserver = hs
});
});
diff --git a/MatrixRoomUtils.Web/Pages/LoginPage.razor b/MatrixRoomUtils.Web/Pages/LoginPage.razor
index c926a93..b6f244d 100644
--- a/MatrixRoomUtils.Web/Pages/LoginPage.razor
+++ b/MatrixRoomUtils.Web/Pages/LoginPage.razor
@@ -1,36 +1,50 @@
@page "/Login"
@using System.Text.Json
+@using System.Text.Json.Serialization
+@using LibMatrix
@inject ILocalStorageService LocalStorage
@inject IJSRuntime JsRuntime
<h3>Login</h3>
<hr/>
-<span>
+<span style="display: block;">
+ <label>User ID:</label>
<span>@@</span><!--
--><FancyTextBox @bind-Value="@newRecordInput.Username"></FancyTextBox><!--
--><span>:</span><!--
--><FancyTextBox @bind-Value="@newRecordInput.Homeserver"></FancyTextBox>
- via
- <FancyTextBox @bind-Value="@newRecordInput.Proxy"></FancyTextBox>
</span>
<span style="display: block;">
<label>Password:</label>
<FancyTextBox @bind-Value="@newRecordInput.Password" IsPassword="true"></FancyTextBox>
</span>
-<button @onclick="AddRecord">Add account to queue</button>
+<span style="display: block">
+ <label>Proxy (<a href="https://cgit.rory.gay/matrix/MxApiExtensions.git">MxApiExtensions</a> or similar):</label>
+ <FancyTextBox @bind-Value="@newRecordInput.Proxy"></FancyTextBox>
+</span>
+<br/>
+<LinkButton OnClick="@AddRecord">Add account to queue</LinkButton>
+<LinkButton OnClick="@(() => Login(newRecordInput))">Log in</LinkButton>
+<br/>
<br/>
+<h4>Import from TSV</h4>
+<hr/>
+<span>Import credentials from a TSV (Tab Separated Values) file</span><br/>
+<span>Columns: username, homeserver, password, proxy</span><br/>
+<span>Keep in mind there is no column header!</span><br/>
+<br/>
<InputFile OnChange="@FileChanged" accept=".tsv"></InputFile>
<br/>
-<br/><br/>
-<h4>Parsed records</h4>
-<hr/>
+<br/>
+
<table border="1">
- <thead>
- <td>Username</td>
- <td>Homeserver</td>
- <td>Password</td>
- <td>Proxy</td>
+ <thead style="border-bottom: 1px solid white;">
+ <th style="min-width: 150px; text-align: center; border-right: 1px solid white;">Username</th>
+ <th style="min-width: 150px; text-align: center; border-right: 1px solid white;">Homeserver</th>
+ <th style="min-width: 150px; text-align: center; border-right: 1px solid white;">Password</th>
+ <th style="min-width: 150px; text-align: center; border-right: 1px solid white;">Proxy</th>
+ <th style="min-width: 150px; text-align: center;">Actions</th>
</thead>
@foreach (var record in records) {
var r = record;
@@ -47,16 +61,28 @@
<td style="border-width: 1px;">
<FancyTextBox @bind-Value="@r.Proxy"></FancyTextBox>
</td>
- <td>
+ <td style="border-width: 1px;">
<a role="button" @onclick="() => records.Remove(r)">Remove</a>
</td>
</tr>
+ @if (r.Exception is MatrixException me) {
+ <tr>
+ <td style="border-width: 1px;">Exception:</td>
+ <td style="border-width: 1px;">@me.ErrorCode</td>
+ <td style="border-width: 1px;" colspan="3">@me.Error</td>
+ </tr>
+ }
+ else if (r.Exception is { } e) {
+ <tr>
+ <td style="border-width: 1px;">Exception:</td>
+ <td style="border-width: 1px;" colspan="4">@e.Message</td>
+ </tr>
+ }
}
</table>
<br/>
-<button @onclick="Login">Login</button>
-<br/>
-<LogView></LogView>
+<LinkButton OnClick="@LoginAll">Log in</LinkButton>
+
@code {
readonly List<LoginStruct> records = new();
@@ -64,29 +90,37 @@
List<UserAuth>? LoggedInSessions { get; set; } = new();
- async Task Login() {
- var loginTasks = records.Select(async record => {
- if (LoggedInSessions.Any(x => x.UserId == $"@{record.Username}:{record.Homeserver}" && x.Proxy == record.Proxy)) return;
- try {
- var result = new UserAuth(await hsProvider.Login(record.Homeserver, record.Username, record.Password, record.Proxy)) {
- Proxy = record.Proxy
- };
- if (result == null) {
- Console.WriteLine($"Failed to login to {record.Homeserver} as {record.Username}!");
- return;
- }
- Console.WriteLine($"Obtained access token for {result.UserId}!");
+ async Task LoginAll() {
+ var loginTasks = records.Select(Login);
+ await Task.WhenAll(loginTasks);
+ }
- await MRUStorage.AddToken(result);
- LoggedInSessions = await MRUStorage.GetAllTokens();
- }
- catch (Exception e) {
+ async Task Login(LoginStruct record) {
+ if (!records.Contains(record))
+ records.Add(record);
+ if (LoggedInSessions.Any(x => x.UserId == $"@{record.Username}:{record.Homeserver}" && x.Proxy == record.Proxy)) return;
+ StateHasChanged();
+ try {
+ var result = new UserAuth(await hsProvider.Login(record.Homeserver, record.Username, record.Password, record.Proxy)) {
+ Proxy = record.Proxy
+ };
+ if (result == null) {
Console.WriteLine($"Failed to login to {record.Homeserver} as {record.Username}!");
- Console.WriteLine(e);
+ return;
}
- StateHasChanged();
- });
- await Task.WhenAll(loginTasks);
+
+ Console.WriteLine($"Obtained access token for {result.UserId}!");
+
+ await MRUStorage.AddToken(result);
+ LoggedInSessions = await MRUStorage.GetAllTokens();
+ }
+ catch (Exception e) {
+ Console.WriteLine($"Failed to login to {record.Homeserver} as {record.Username}!");
+ Console.WriteLine(e);
+ record.Exception = e;
+ }
+
+ StateHasChanged();
}
private async Task FileChanged(InputFileChangeEventArgs obj) {
@@ -118,6 +152,9 @@
public string? Username { get; set; } = "";
public string? Password { get; set; } = "";
public string? Proxy { get; set; }
+
+ [JsonIgnore]
+ internal Exception? Exception { get; set; }
}
}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Web/Pages/ServerInfo.razor b/MatrixRoomUtils.Web/Pages/ServerInfo.razor
index 5b3f1c1..71a1980 100644
--- a/MatrixRoomUtils.Web/Pages/ServerInfo.razor
+++ b/MatrixRoomUtils.Web/Pages/ServerInfo.razor
@@ -80,7 +80,7 @@
protected override async Task OnParametersSetAsync() {
if (Homeserver is not null) {
var rhs = await hsProvider.GetRemoteHomeserver(Homeserver);
- ServerVersionResponse = await rhs.GetServerVersionAsync();
+ ServerVersionResponse = await (rhs.FederationClient?.GetServerVersionAsync() ?? Task.FromResult<ServerVersionResponse?>(null));
ClientVersionsResponse = await rhs.GetClientVersionsAsync();
}
base.OnParametersSetAsync();
diff --git a/MatrixRoomUtils.Web/wwwroot/index.html b/MatrixRoomUtils.Web/wwwroot/index.html
index 3fc740a..7eef159 100644
--- a/MatrixRoomUtils.Web/wwwroot/index.html
+++ b/MatrixRoomUtils.Web/wwwroot/index.html
@@ -10,6 +10,7 @@
<link href="css/app.css" rel="stylesheet"/>
<link href="favicon.png" rel="icon" type="image/png"/>
<link href="MatrixRoomUtils.Web.styles.css" rel="stylesheet"/>
+ <link rel="manifest" href="mru.webmanifest" />
</head>
<body>
diff --git a/MatrixRoomUtils.Web/wwwroot/mru.webmanifest b/MatrixRoomUtils.Web/wwwroot/mru.webmanifest
new file mode 100644
index 0000000..ef1ee66
--- /dev/null
+++ b/MatrixRoomUtils.Web/wwwroot/mru.webmanifest
@@ -0,0 +1,16 @@
+{
+ "name": "Rory&::MatrixUtils",
+ "short_name": "MRU",
+ "description": "A collection of Matrix utilities.",
+ "icons": [
+ {
+ "src": "icon-192.png",
+ "sizes": "192x192",
+ "type": "image/png"
+ }
+ ],
+ "start_url": "/index.html",
+ "display": "fullscreen",
+ "theme_color": "#052767",
+ "background_color": "#3A0647"
+}
diff --git a/reset-submodules.sh b/reset-submodules.sh
new file mode 100755
index 0000000..60f2267
--- /dev/null
+++ b/reset-submodules.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+find . -type d | grep --invert '\.git' | while read dir
+do
+ (
+ (git -C $dir submodule init 2>/dev/null) \
+ && (git -C $dir submodule update 2>/dev/null)
+ ) || echo $dir does not contain submodules
+done
|