@page "/admin/federation"
@using Iceshrimp.Backend.Components.Admin
@using Iceshrimp.Backend.Core.Configuration
@using Iceshrimp.Backend.Core.Database.Tables
@using Iceshrimp.Backend.Core.Extensions
@using Iceshrimp.Backend.Core.Middleware
@using Microsoft.EntityFrameworkCore
@using Microsoft.Extensions.Options
@using static Iceshrimp.Backend.Core.Configuration.Enums;
@using Microsoft.AspNetCore.Components.Forms
@inherits AdminComponentBase
Host |
Imported |
@if (IsBlocklist)
{
Reason |
}
Actions |
@if (IsBlocklist)
{
@foreach (var instance in _blockedInstances)
{
@{
var host = instance.Host;
if (host.StartsWith("xn--"))
host = $"{host.FromPunycode()} ({host})";
}
@host |
@(instance.IsImported ? "Yes" : "No")
|
@if (instance.Reason is not null)
{
@instance.Reason
}
else
{
No reason set
}
|
Unblock
|
}
}
else
{
@foreach (var instance in _allowedInstances)
{
@{
var host = instance.Host;
if (host.StartsWith("xn--"))
host = host.FromPunycode() + $"({instance.Host})";
}
@host |
@(instance.IsImported ? "Yes" : "No")
|
Remove
|
}
}
@if (_blockedInstances is [] && _allowedInstances is [])
{
No instances listed.
}
@if (Offset is > 0)
{
}
else
{
}
@if (_blockedInstances.Length == 50 || _allowedInstances.Length == 50)
{
}
else
{
}
Add @ModeString.ToLowerInvariant() instance
@if (IsBlocklist)
{
}
else
{
}
@code {
[Inject] public required IOptionsSnapshot Options { get; set; }
[SupplyParameterFromQuery] public int? Offset { get; set; }
[SupplyParameterFromForm] private FederationModel Model { get; set; } = null!;
private bool IsBlocklist => Options.Value.FederationMode == FederationMode.BlockList;
private string ModeString => IsBlocklist ? "Blocked" : "Allowed";
private BlockedInstance[] _blockedInstances = [];
private AllowedInstance[] _allowedInstances = [];
private class FederationModel
{
public string? Host { get; set; }
public string? Reason { get; set; }
public void Canonicalize()
{
Host = Host?.Trim().ToPunycodeLower();
Reason = Reason?.Trim();
if (Host?.Length == 0)
Host = null;
if (Reason?.Length == 0)
Reason = null;
}
}
protected override void OnParametersSet()
{
// ReSharper disable once NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract
Model ??= new FederationModel();
}
protected override async Task OnGet()
{
if (IsBlocklist)
_blockedInstances = await Database.BlockedInstances.OrderBy(p => p.Host).Skip(Offset ?? 0).Take(50).ToArrayAsync();
else
_allowedInstances = await Database.AllowedInstances.OrderBy(p => p.Host).Skip(Offset ?? 0).Take(50).ToArrayAsync();
}
private async Task OnSubmit()
{
Model.Canonicalize();
if (Model.Host == null)
throw GracefulException.BadRequest("Missing host field");
if (IsBlocklist)
{
if (await Database.BlockedInstances.FirstOrDefaultAsync(p => p.Host == Model.Host) is { } instance)
{
instance.Reason = Model.Reason;
instance.IsImported = false;
}
else
{
var newInstance = new BlockedInstance
{
Host = Model.Host,
Reason = Model.Reason,
IsImported = false
};
Database.Add(newInstance);
}
}
else
{
if (!await Database.AllowedInstances.AnyAsync(p => p.Host == Model.Host))
{
var newInstance = new AllowedInstance { Host = Model.Host, IsImported = false };
Database.Add(newInstance);
}
}
await Database.SaveChangesAsync();
ReloadPage();
}
}