mirror of
https://github.com/spacebarchat/server.git
synced 2026-10-23 13:03:08 +00:00
Local changes
This commit is contained in:
1 parent
a632666203
commit
abb1b570a4
73 files changed
+2067
-64
No files matched your search
@@ -0,0 +1,107 @@
|
||||
@page "/"
|
||||
@using System.Net.Http.Headers
|
||||
@using Spacebar.AdminAPI.TestClient.Services
|
||||
@inject Config Config
|
||||
@inject ILocalStorageService LocalStorage
|
||||
|
||||
<PageTitle>Home</PageTitle>
|
||||
|
||||
<span style="@($"color: {(IsApiUrlValid ? "green" : "red")};")">Spacebar API URL: </span>
|
||||
<InputText @bind-Value:get="Config.ApiUrl" @bind-Value:set="@(async (v) => {
|
||||
Config.ApiUrl = v!;
|
||||
await ValidateAndSaveConfig();
|
||||
})"/>
|
||||
<br/>
|
||||
|
||||
<!-- <span style="@($"color: {(IsGatewayUrlValid ? "green" : "red")};")">Spacebar Gateway URL: </span> -->
|
||||
<!-- <InputText @bind-Value="GatewayUrl" /> -->
|
||||
<!-- <br /> -->
|
||||
|
||||
<span style="@($"color: {(IsCdnUrlValid ? "green" : "red")};")">Spacebar CDN URL: </span>
|
||||
<InputText @bind-Value:get="Config.CdnUrl" @bind-Value:set="@(async (v) => {
|
||||
Config.CdnUrl = v!;
|
||||
await ValidateAndSaveConfig();
|
||||
})"/>
|
||||
<br/>
|
||||
|
||||
<span style="@($"color: {(IsAdminApiUrlValid ? "green" : "red")};")">Spacebar Admin API URL: </span>
|
||||
<InputText @bind-Value:get="Config.AdminUrl" @bind-Value:set="@(async (v) => {
|
||||
Config.AdminUrl = v!;
|
||||
await ValidateAndSaveConfig();
|
||||
})"/>
|
||||
<br/>
|
||||
|
||||
<span style="@($"color: {(IsAccessTokenValid ? "green" : "red")};")">Access Token: </span>
|
||||
<InputText @bind-Value:get="Config.AccessToken" @bind-Value:set="@(async (v) => {
|
||||
Config.AccessToken = v!;
|
||||
await ValidateAndSaveConfig();
|
||||
})"/>
|
||||
<a href="/login">New access token</a>
|
||||
<br/>
|
||||
|
||||
@code {
|
||||
|
||||
private bool IsApiUrlValid { get; set; }
|
||||
|
||||
// private bool IsGatewayUrlValid { get; set; }
|
||||
private bool IsCdnUrlValid { get; set; }
|
||||
private bool IsAdminApiUrlValid { get; set; }
|
||||
private bool IsAccessTokenValid { get; set; }
|
||||
|
||||
protected override async Task OnInitializedAsync() {
|
||||
await ValidateAndSaveConfig();
|
||||
}
|
||||
|
||||
private async Task ValidateAndSaveConfig() {
|
||||
await LocalStorage.SetItemAsync("sb_admin_tc_config", Config);
|
||||
|
||||
using var hc = new HttpClient();
|
||||
HttpResponseMessage response;
|
||||
try {
|
||||
response = await hc.GetAsync(Config.ApiUrl + "/api/v9/policies/instance/domains");
|
||||
IsApiUrlValid = response.IsSuccessStatusCode;
|
||||
}
|
||||
catch {
|
||||
IsApiUrlValid = false;
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
|
||||
// response = await hc.GetAsync(Config.GatewayUrl + "/api/v9/policies/instance");
|
||||
// IsGatewayUrlValid = response.IsSuccessStatusCode;
|
||||
// StateHasChanged();
|
||||
|
||||
try {
|
||||
response = await hc.GetAsync(Config.CdnUrl + "/ping");
|
||||
IsCdnUrlValid = response.IsSuccessStatusCode;
|
||||
}
|
||||
catch {
|
||||
IsCdnUrlValid = false;
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
|
||||
try {
|
||||
response = await hc.GetAsync(Config.AdminUrl + "/_spacebar/admin/ping");
|
||||
IsAdminApiUrlValid = response.IsSuccessStatusCode;
|
||||
}
|
||||
catch {
|
||||
IsAdminApiUrlValid = false;
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
|
||||
try {
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, Config.AdminUrl + "/_spacebar/admin/whoami");
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", Config.AccessToken);
|
||||
response = await hc.SendAsync(request);
|
||||
IsAccessTokenValid = response.IsSuccessStatusCode;
|
||||
}
|
||||
catch {
|
||||
IsAccessTokenValid = false;
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
@page "/Login"
|
||||
@using System.Text.Json.Nodes
|
||||
@using Spacebar.AdminAPI.TestClient.Services
|
||||
@inject ILocalStorageService LocalStorage
|
||||
@inject Config Config
|
||||
@inject NavigationManager Navigation
|
||||
<h3>Login</h3>
|
||||
|
||||
<span>Email: </span>
|
||||
<InputText @bind-Value="Email"/>
|
||||
<br/>
|
||||
|
||||
<span>Password: </span>
|
||||
<InputText type="password" @bind-Value="Password"/>
|
||||
<br/>
|
||||
|
||||
<button @onclick="DoLogin">Login</button>
|
||||
<br/>
|
||||
|
||||
<pre style="color: red; font-family: 'JetBrains Mono',monospace">@Error</pre>
|
||||
|
||||
|
||||
@code {
|
||||
private string Email { get; set; }
|
||||
private string Password { get; set; }
|
||||
private string Error { get; set; }
|
||||
|
||||
private async Task DoLogin() {
|
||||
HttpResponseMessage response;
|
||||
using var hc = new HttpClient();
|
||||
|
||||
try {
|
||||
response = await hc.PostAsJsonAsync(Config.ApiUrl + "/api/v9/auth/login", new {
|
||||
login = Email,
|
||||
password = Password,
|
||||
login_source = "Spacebar Admin API Test Client",
|
||||
undelete = false
|
||||
});
|
||||
}
|
||||
catch (Exception e) {
|
||||
Error = e.ToString();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!response.IsSuccessStatusCode) {
|
||||
Error = await response.Content.ReadAsStringAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
var content = await response.Content.ReadFromJsonAsync<JsonObject>();
|
||||
var accessToken = content!["token"].ToString();
|
||||
Config.AccessToken = accessToken;
|
||||
await LocalStorage.SetItemAsync("sb_admin_tc_config", Config);
|
||||
Navigation.NavigateTo("/", true, true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
@page "/Users"
|
||||
@using System.Net.Http.Headers
|
||||
@using System.Reflection
|
||||
@using Spacebar.AdminApi.Models
|
||||
@using Spacebar.AdminAPI.TestClient.Services
|
||||
@using ArcaneLibs.Blazor.Components
|
||||
@inject Config Config
|
||||
@inject ILocalStorageService LocalStorage
|
||||
|
||||
<PageTitle>Users</PageTitle>
|
||||
|
||||
<details>
|
||||
<summary>Displayed columns</summary>
|
||||
@foreach (var column in DisplayedColumns) {
|
||||
var value = column.Value;
|
||||
<span>
|
||||
<InputCheckbox @bind-Value:get="@(value)" @bind-Value:set="@(b => {
|
||||
DisplayedColumns[column.Key] = b;
|
||||
StateHasChanged();
|
||||
})"/>
|
||||
@column.Key.Name
|
||||
</span>
|
||||
<br/>
|
||||
}
|
||||
</details>
|
||||
|
||||
<table class="table table-bordered">
|
||||
@{
|
||||
var columns = DisplayedColumns.Where(kvp => kvp.Value).Select(kvp => kvp.Key).ToList();
|
||||
}
|
||||
<thead>
|
||||
<tr>
|
||||
@foreach (var column in columns) {
|
||||
<th>@column.Name</th>
|
||||
}
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var user in UserList) {
|
||||
<tr>
|
||||
@foreach (var column in columns) {
|
||||
<td>@column.GetValue(user)</td>
|
||||
}
|
||||
<td>
|
||||
<LinkButton href="@($"/Users/Delete/{user.Id}")" Color="#ff0000">Delete</LinkButton>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@code {
|
||||
|
||||
private Dictionary<PropertyInfo, bool> DisplayedColumns { get; set; } = typeof(UserModel).GetProperties()
|
||||
.ToDictionary(p => p, p => p.Name == "Username" || p.Name == "Id" || p.Name == "MessageCount");
|
||||
|
||||
private List<UserModel> UserList { get; set; } = new();
|
||||
|
||||
protected override async Task OnInitializedAsync() {
|
||||
using var hc = new HttpClient();
|
||||
hc.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Config.AccessToken);
|
||||
var response = await hc.GetAsync(Config.AdminUrl + "/_spacebar/admin/users/");
|
||||
if (!response.IsSuccessStatusCode) throw new Exception(await response.Content.ReadAsStringAsync());
|
||||
var content = response.Content.ReadFromJsonAsAsyncEnumerable<UserModel>();
|
||||
await foreach (var user in content) {
|
||||
UserList.Add(user);
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
@page "/Users/Delete/{Id}"
|
||||
@using System.Net.Http.Headers
|
||||
@using System.Text.Json
|
||||
@using System.Text.Json.Nodes
|
||||
@using ArcaneLibs.Extensions
|
||||
@using Spacebar.AdminApi.Models
|
||||
@using Spacebar.AdminAPI.TestClient.Services
|
||||
@inject Config Config
|
||||
<h3>UsersDelete - @Id</h3>
|
||||
|
||||
Deleted @ChannelDeleteProgress.Sum(x=>x.Value.Deleted) messages so far!
|
||||
@foreach (var (channel, progress) in ChannelDeleteProgress.Where(x=>x.Value.Deleted != x.Value.Total).OrderByDescending(x=>x.Value.Progress)) {
|
||||
<div>@channel: @progress.Total total, @progress.Deleted deleted</div>
|
||||
<progress max="@progress.Total" value="@progress.Deleted"></progress>
|
||||
}
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter]
|
||||
public required string Id { get; set; }
|
||||
|
||||
private Dictionary<string, DeleteProgress> ChannelDeleteProgress { get; set; } = new();
|
||||
|
||||
protected override async Task OnInitializedAsync() {
|
||||
using var hc = new HttpClient();
|
||||
hc.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Config.AccessToken);
|
||||
var response = await hc.GetAsync(Config.AdminUrl + $"/_spacebar/admin/Users/{Id}/delete?messageDeleteChunkSize=100");
|
||||
if (!response.IsSuccessStatusCode) throw new Exception(await response.Content.ReadAsStringAsync());
|
||||
var content = response.Content.ReadFromJsonAsAsyncEnumerable<AsyncActionResult>();
|
||||
await foreach (var actionResult in content) {
|
||||
Console.WriteLine(actionResult.ToJson(indent: false));
|
||||
switch (actionResult.MessageType) {
|
||||
case "STATS": {
|
||||
var data = JsonSerializer.Deserialize<JsonObject>(actionResult.Data.ToJson());
|
||||
ChannelDeleteProgress = data!["messages_per_channel"]!
|
||||
.Deserialize<Dictionary<string, int>>()!
|
||||
.ToDictionary(x=>x.Key, x=>new DeleteProgress { Total = x.Value });
|
||||
break;
|
||||
}
|
||||
case "BULK_DELETED": {
|
||||
var data = JsonSerializer.Deserialize<JsonObject>(actionResult.Data.ToJson());
|
||||
ChannelDeleteProgress[data!["channel_id"]!.ToString()].Deleted += data!["deleted"]!.GetValue<int>();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Console.WriteLine($"Unknown message type: {actionResult.MessageType}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
await Task.Delay(1);
|
||||
}
|
||||
}
|
||||
|
||||
private class DeleteProgress {
|
||||
public int Total { get; set; }
|
||||
public int Deleted { get; set; } = 0;
|
||||
public float Progress => (float)Deleted / Total;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user