summary refs log tree commit diff
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2025-12-25 07:07:31 +0100
committerRory& <root@rory.gay>2025-12-25 07:07:31 +0100
commita01fb6ab39cca9c54713e9db5415a574f68f2e71 (patch)
treec8b6d58ea48b63eafdf0f18af65edd469c376516
parentConsistent imports and instructions for email (diff)
downloadserver-ts-a01fb6ab39cca9c54713e9db5415a574f68f2e71.tar.xz
WIP C# stuff
-rw-r--r--extra/admin-api/DiscordEmojiConverter/DiscordEmojiConverter.csproj14
-rw-r--r--extra/admin-api/DiscordEmojiConverter/DiscordEmojiJson.cs55
-rw-r--r--extra/admin-api/DiscordEmojiConverter/Program.cs27
-rw-r--r--extra/admin-api/Spacebar.ConfigModel/Class1.cs71
-rw-r--r--extra/admin-api/Spacebar.ConfigModel/DefaultsConfiguration.cs37
-rw-r--r--extra/admin-api/Spacebar.ConfigModel/GeneralConfiguration.cs35
-rw-r--r--extra/admin-api/Spacebar.ConfigModel/LimitsConfiguration.cs12
-rw-r--r--extra/admin-api/Spacebar.ConfigModel/SecurityConfiguration.cs26
-rw-r--r--extra/admin-api/Spacebar.ConfigModel/ServerConfiguration.cs106
-rw-r--r--extra/admin-api/Utilities/Spacebar.AdminApi.TestClient/Pages/ServerConfig.razor26
10 files changed, 358 insertions, 51 deletions
diff --git a/extra/admin-api/DiscordEmojiConverter/DiscordEmojiConverter.csproj b/extra/admin-api/DiscordEmojiConverter/DiscordEmojiConverter.csproj
new file mode 100644

index 00000000..72d306b3 --- /dev/null +++ b/extra/admin-api/DiscordEmojiConverter/DiscordEmojiConverter.csproj
@@ -0,0 +1,14 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <OutputType>Exe</OutputType> + <TargetFramework>net10.0</TargetFramework> + <ImplicitUsings>enable</ImplicitUsings> + <Nullable>enable</Nullable> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="ArcaneLibs" Version="1.0.0-preview.20251207-164820" /> + </ItemGroup> + +</Project> diff --git a/extra/admin-api/DiscordEmojiConverter/DiscordEmojiJson.cs b/extra/admin-api/DiscordEmojiConverter/DiscordEmojiJson.cs new file mode 100644
index 00000000..71c4a53f --- /dev/null +++ b/extra/admin-api/DiscordEmojiConverter/DiscordEmojiJson.cs
@@ -0,0 +1,55 @@ +using System.Text.Json.Serialization; + +namespace DiscordEmojiConverter; + +public class DiscordEmojiJson { + [JsonPropertyName("emojis")] + public List<DiscordEmoji>? Emojis { get; set; } + + [JsonPropertyName("emojisByCategory")] + public Dictionary<string, List<int>>? EmojisByCategory { get; set; } + + [JsonPropertyName("nameToEmoji")] + public Dictionary<string, int>? NameToEmoji { get; set; } + + [JsonPropertyName("surrogateToEmoji")] + public Dictionary<string, int>? SurrogateToEmoji { get; set; } + + [JsonPropertyName("numDiversitySprites")] + public int? NumDiversitySprites { get; set; } + + [JsonPropertyName("numNonDiversitySprites")] + public int? NumNonDiversitySprites { get; set; } +} + +public class DiscordEmoji { + [JsonPropertyName("names")] + public List<string>? Names { get; set; } + + [JsonPropertyName("surrogates")] + public string? Surrogates { get; set; } + + [JsonPropertyName("unicodeVersion")] + public float? UnicodeVersion { get; set; } + + [JsonPropertyName("spriteIndex")] + public int? SpriteIndex { get; set; } + + [JsonPropertyName("hasMultiDiversity")] + public bool? HasMultiDiversity { get; set; } + + [JsonPropertyName("hasMultiDiversityParent")] + public bool? HasMultiDiversityParent { get; set; } + + [JsonPropertyName("hasDiversity")] + public bool? HasDiversity { get; set; } + + [JsonPropertyName("hasDiversityParent")] + public bool? HasDiversityParent { get; set; } + + [JsonPropertyName("diversityChildren")] + public List<int>? DiversityChildren { get; set; } + + [JsonPropertyName("diversity")] + public List<string>? Diversity { get; set; } +} \ No newline at end of file diff --git a/extra/admin-api/DiscordEmojiConverter/Program.cs b/extra/admin-api/DiscordEmojiConverter/Program.cs new file mode 100644
index 00000000..96593958 --- /dev/null +++ b/extra/admin-api/DiscordEmojiConverter/Program.cs
@@ -0,0 +1,27 @@ +// See https://aka.ms/new-console-template for more information + +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Text.Json.Serialization; +using ArcaneLibs.Extensions; +using DiscordEmojiConverter; + +var emojis = JsonSerializer.Deserialize<DiscordEmojiJson>(File.OpenRead(args[0]), + new JsonSerializerOptions() { UnmappedMemberHandling = JsonUnmappedMemberHandling.Disallow }); + +emojis.SurrogateToEmoji = null; +emojis.NameToEmoji = null; +emojis.NumDiversitySprites = null; +emojis.NumNonDiversitySprites = null; + +foreach (var emoji in emojis.Emojis!) +{ + emoji.HasDiversity = null; + emoji.HasDiversityParent = null; + emoji.HasMultiDiversity = null; + emoji.HasMultiDiversityParent = null; + emoji.SpriteIndex = null; + emoji.UnicodeVersion = null; +} + +Console.WriteLine(emojis.ToJson(ignoreNull: true, indent: false)); \ No newline at end of file diff --git a/extra/admin-api/Spacebar.ConfigModel/Class1.cs b/extra/admin-api/Spacebar.ConfigModel/Class1.cs
index 948ca91a..26e9d0fc 100644 --- a/extra/admin-api/Spacebar.ConfigModel/Class1.cs +++ b/extra/admin-api/Spacebar.ConfigModel/Class1.cs
@@ -2,63 +2,32 @@ namespace Spacebar.ConfigModel; -public class Config -{ - [JsonPropertyName("admin")] public EndpointConfig Admin { get; set; } = null!; - [JsonPropertyName("api")] public EndpointConfig Api { get; set; } = null!; - [JsonPropertyName("gateway")] public EndpointConfig Gateway { get; set; } = null!; - [JsonPropertyName("cdn")] public EndpointConfig Cdn { get; set; } = null!; +public class Config { + [JsonPropertyName("admin")] + public EndpointConfig Admin { get; set; } = null!; - public Config ReadFromKv(Dictionary<string, object?> kv) - { - // to object - + [JsonPropertyName("api")] + public EndpointConfig Api { get; set; } = null!; - foreach (var (key, value) in kv) - { - switch (key.Split('_', 2)[0]) - { - default: - Console.WriteLine($"Unrecognized config key prefix: {key}"); - continue; - } - } + [JsonPropertyName("gateway")] + public EndpointConfig Gateway { get; set; } = null!; - return this; - } + [JsonPropertyName("cdn")] + public EndpointConfig Cdn { get; set; } = null!; } -public class EndpointConfig -{ - [JsonPropertyName("endpointPrivate")] public string? EndpointPrivate { get; set; } - [JsonPropertyName("endpointPublic")] public string? EndpointPublic { get; set; } +public class EndpointConfig { + [JsonPropertyName("endpointPrivate")] + public string? EndpointPrivate { get; set; } - public EndpointConfig ReadFromKv(Dictionary<string, object?> kv, string prefix) - { - foreach (var (key, value) in kv) - { - if (!key.StartsWith(prefix + "_")) continue; - var subKey = key[(prefix + "_").Length..]; - switch (subKey) - { - case "ENDPOINT_PRIVATE": - EndpointPrivate = value?.ToString(); - break; - case "ENDPOINT_PUBLIC": - EndpointPublic = value?.ToString(); - break; - default: - Console.WriteLine($"Unrecognized config key: {key}"); - break; - } - } - - return this; - } + [JsonPropertyName("endpointPublic")] + public string? EndpointPublic { get; set; } } -public class ApiConfig : EndpointConfig -{ - [JsonPropertyName("activeVersions")] public List<string> ActiveVersions { get; set; } = null!; - [JsonPropertyName("defaultVersion")] public string DefaultVersion { get; set; } = null!; +public class ApiConfig : EndpointConfig { + [JsonPropertyName("activeVersions")] + public List<string> ActiveVersions { get; set; } = null!; + + [JsonPropertyName("defaultVersion")] + public string DefaultVersion { get; set; } = null!; } \ No newline at end of file diff --git a/extra/admin-api/Spacebar.ConfigModel/DefaultsConfiguration.cs b/extra/admin-api/Spacebar.ConfigModel/DefaultsConfiguration.cs new file mode 100644
index 00000000..884f3d54 --- /dev/null +++ b/extra/admin-api/Spacebar.ConfigModel/DefaultsConfiguration.cs
@@ -0,0 +1,37 @@ +using System.Text.Json.Serialization; + +namespace Spacebar.ConfigModel; + +public class DefaultsConfiguration +{ + [JsonPropertyName("guild")] public GuildDefaults Guild = new GuildDefaults(); + [JsonPropertyName("user")] public ChannelDefaults Channel = new ChannelDefaults(); +} + +public class GuildDefaults +{ + [JsonPropertyName("maxPresences")] public int MaxPresences { get; set; } = 250000; + + [JsonPropertyName("maxVideoChannelUsers")] + public int MaxVideoChannelUsers { get; set; } = 200; + + [JsonPropertyName("afkTimeout")] public int AfkTimeout { get; set; } = 300; + + [JsonPropertyName("defaultMessageNotifications")] + public int DefaultMessageNotifications { get; set; } = 1; + + [JsonPropertyName("explicitContentFilter")] + public int ExplicitContentFilter { get; set; } = 0; +} + +public class ChannelDefaults +{ + [JsonPropertyName("premium")] + public bool Premium { get; set; } = true; + + [JsonPropertyName("premiumType")] + public int PremiumType { get; set; } = 2; + + [JsonPropertyName("verified")] + public bool Verified { get; set; } = true; +} \ No newline at end of file diff --git a/extra/admin-api/Spacebar.ConfigModel/GeneralConfiguration.cs b/extra/admin-api/Spacebar.ConfigModel/GeneralConfiguration.cs new file mode 100644
index 00000000..1e006759 --- /dev/null +++ b/extra/admin-api/Spacebar.ConfigModel/GeneralConfiguration.cs
@@ -0,0 +1,35 @@ +using System.Text.Json.Serialization; + +namespace Spacebar.ConfigModel; + +public class GeneralConfiguration { + [JsonPropertyName("instanceName")] + public string InstanceName { get; set; } = "Spacebar Instance"; + + [JsonPropertyName("serverName")] + public string? ServerName { get; set; } = null; + + [JsonPropertyName("instanceDescription")] + public string InstanceDescription { get; set; } = "This is a Spacebar instance made in the pre-release days"; + + [JsonPropertyName("frontPage")] + public string? FrontPage { get; set; } = null; + + [JsonPropertyName("tosPage")] + public string? TosPage { get; set; } = null; + + [JsonPropertyName("correspondenceEmail")] + public string? CorrespondenceEmail { get; set; } = null; + + [JsonPropertyName("correspondenceUserID")] + public string? CorrespondenceUserID { get; set; } = null; + + [JsonPropertyName("image")] + public string? Image { get; set; } = null; + + [JsonPropertyName("instanceId")] + public string InstanceId { get; set; } = null!; // {get;set;}=Snowflake.generate(); + + [JsonPropertyName("autoCreateBotUsers")] + public bool AutoCreateBotUsers { get; set; } = false; +} \ No newline at end of file diff --git a/extra/admin-api/Spacebar.ConfigModel/LimitsConfiguration.cs b/extra/admin-api/Spacebar.ConfigModel/LimitsConfiguration.cs new file mode 100644
index 00000000..8a773744 --- /dev/null +++ b/extra/admin-api/Spacebar.ConfigModel/LimitsConfiguration.cs
@@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Spacebar.ConfigModel; + +public class LimitsConfiguration { + [JsonPropertyName("user")] public UserLimits User = new UserLimits(); + [JsonPropertyName("guild")] public GuildLimits Guild = new GuildLimits(); + [JsonPropertyName("message")] public MessageLimits Message = new MessageLimits(); + [JsonPropertyName("channel")] public ChannelLimits Channel = new ChannelLimits(); + [JsonPropertyName("rate")] public RateLimits Rate = new RateLimits(); + [JsonPropertyName("absoluteRate")] public GlobalRateLimits AbsoluteRate = new GlobalRateLimits(); +} \ No newline at end of file diff --git a/extra/admin-api/Spacebar.ConfigModel/SecurityConfiguration.cs b/extra/admin-api/Spacebar.ConfigModel/SecurityConfiguration.cs new file mode 100644
index 00000000..017e89ba --- /dev/null +++ b/extra/admin-api/Spacebar.ConfigModel/SecurityConfiguration.cs
@@ -0,0 +1,26 @@ +using System.Text.Json.Serialization; + +namespace Spacebar.ConfigModel; + +public class SecurityConfiguration +{ + [JsonPropertyName("captcha")] public CaptchaConfiguration Captcha = new CaptchaConfiguration(); + [JsonPropertyName("twoFactor")] public TwoFactorConfiguration TwoFactor = new TwoFactorConfiguration(); + [JsonPropertyName("autoUpdate")] public bool AutoUpdate = true; + [JsonPropertyName("requestSignature")] public string RequestSignature; // = crypto.randomBytes(32).toString("base64"); + [JsonPropertyName("jwtSecret")] public string? JwtSecret = null; + [JsonPropertyName("forwardedFor")] public string? ForwardedFor = null; + [JsonPropertyName("trustedProxies")] public string TrustedProxies = null; + [JsonPropertyName("abuseIpDbApiKey")] public string? AbuseIpDbApiKey = null; + [JsonPropertyName("abuseipdbBlacklistRatelimit")] public int AbuseipdbBlacklistRatelimit = 5; + [JsonPropertyName("abuseipdbConfidenceScoreTreshold")] public int AbuseipdbConfidenceScoreTreshold = 50; + [JsonPropertyName("ipdataApiKey")] public string? IpdataApiKey = null; + [JsonPropertyName("mfaBackupCodeCount")] public int MfaBackupCodeCount = 10; + [JsonPropertyName("statsWorldReadable")] public bool StatsWorldReadable = true; + [JsonPropertyName("defaultRegistrationTokenExpiration")] public int DefaultRegistrationTokenExpiration = 1000 * 60 * 60 * 24 * 7; + [JsonPropertyName("cdnSignUrls")] public bool CdnSignUrls = false; + [JsonPropertyName("cdnSignatureKey")] public string CdnSignatureKey = crypto.randomBytes(32).toString("base64"); + [JsonPropertyName("cdnSignatureDuration")] public string CdnSignatureDuration = "24h"; + [JsonPropertyName("cdnSignatureIncludeIp")] public bool CdnSignatureIncludeIp = true; + [JsonPropertyName("cdnSignatureIncludeUserAgent")] public bool CdnSignatureIncludeUserAgent = true; +} \ No newline at end of file diff --git a/extra/admin-api/Spacebar.ConfigModel/ServerConfiguration.cs b/extra/admin-api/Spacebar.ConfigModel/ServerConfiguration.cs new file mode 100644
index 00000000..49309ab1 --- /dev/null +++ b/extra/admin-api/Spacebar.ConfigModel/ServerConfiguration.cs
@@ -0,0 +1,106 @@ +using System.Text.Json.Serialization; + +namespace Spacebar.ConfigModel; + +public class ServerConfiguration { + [JsonPropertyName("admin")] public EndpointConfiguration Admin = new EndpointConfiguration(); + [JsonPropertyName("gateway")] public EndpointConfiguration Gateway = new EndpointConfiguration(); + [JsonPropertyName("cdn")] public CdnConfiguration Cdn = new CdnConfiguration(); + [JsonPropertyName("api")] public ApiConfiguration Api = new ApiConfiguration(); + [JsonPropertyName("general")] public GeneralConfiguration General = new GeneralConfiguration(); + [JsonPropertyName("limits")] public LimitsConfiguration Limits = new LimitsConfiguration(); + [JsonPropertyName("security")] public SecurityConfiguration Security = new SecurityConfiguration(); + [JsonPropertyName("login")] public LoginConfiguration Login = new LoginConfiguration(); + [JsonPropertyName("register")] public RegisterConfiguration Register = new RegisterConfiguration(); + [JsonPropertyName("regions")] public RegionConfiguration Regions = new RegionConfiguration(); + [JsonPropertyName("guild")] public GuildConfiguration Guild = new GuildConfiguration(); + [JsonPropertyName("gif")] public GifConfiguration Gif = new GifConfiguration(); + [JsonPropertyName("rabbitmq")] public RabbitMQConfiguration Rabbitmq = new RabbitMQConfiguration(); + [JsonPropertyName("kafka")] public KafkaConfiguration Kafka = new KafkaConfiguration(); + [JsonPropertyName("templates")] public TemplateConfiguration Templates = new TemplateConfiguration(); + [JsonPropertyName("metrics")] public MetricsConfiguration Metrics = new MetricsConfiguration(); + [JsonPropertyName("defaults")] public DefaultsConfiguration Defaults = new DefaultsConfiguration(); + [JsonPropertyName("external")] public ExternalTokensConfiguration External = new ExternalTokensConfiguration(); + [JsonPropertyName("email")] public EmailConfiguration Email = new EmailConfiguration(); + [JsonPropertyName("passwordReset")] public PasswordResetConfiguration PasswordReset = new PasswordResetConfiguration(); + [JsonPropertyName("user")] public UserConfiguration User = new UserConfiguration(); +} + +public class GeneralConfiguration { + [JsonPropertyName("instanceName")] public string InstanceName = "Spacebar Instance"; + + [JsonPropertyName("instanceDescription")] + public string? InstanceDescription = "This is a Spacebar instance made in the pre-release days"; + + [JsonPropertyName("frontPage")] public string? FrontPage = null; + [JsonPropertyName("tosPage")] public string? TosPage = null; + + [JsonPropertyName("correspondenceEmail")] + public string? CorrespondenceEmail = null; + + [JsonPropertyName("correspondenceUserID")] + public string? CorrespondenceUserId = null; + + [JsonPropertyName("image")] public string? Image = null; + [JsonPropertyName("instanceId")] public string InstanceId = Snowflake.generate(); + + [JsonPropertyName("autoCreateBotUsers")] + public bool AutoCreateBotUsers = false; +} + +public class EndpointConfiguration { + [JsonPropertyName("endpointPrivate")] + public string? EndpointPrivate { get; set; } + + [JsonPropertyName("endpointPublic")] + public string? EndpointPublic { get; set; } +} + +public class ApiConfiguration : EndpointConfiguration { + [JsonPropertyName("activeVersions")] + public List<string> ActiveVersions { get; set; } = null!; + + [JsonPropertyName("defaultVersion")] + public string DefaultVersion { get; set; } = null!; +} + +public class CdnConfiguration : EndpointConfiguration { + [JsonPropertyName("resizeHeightMax")] public int ResizeHeightMax = 1000; + [JsonPropertyName("resizeWidthMax")] public int ResizeWidthMax = 1000; + [JsonPropertyName("imagorServerUrl")] public string? ImagorServerUrl = null; + + [JsonPropertyName("proxyCacheHeaderSeconds")] + public int ProxyCacheHeaderSeconds = 60 * 60 * 24; + + [JsonPropertyName("maxAttachmentSize")] + public int MaxAttachmentSize = 25 * 1024 * 1024; // 25 MB + + // limits: CdnLimitsConfiguration = new CdnLimitsConfiguration(); +} + +public class CdnLimitsConfiguration { + // ordered by route register order in CDN... + [JsonPropertyName("icon")] public CdnImageLimitsConfiguration Icon = new CdnImageLimitsConfiguration(); + [JsonPropertyName("roleIcon")] public CdnImageLimitsConfiguration RoleIcon = new CdnImageLimitsConfiguration(); + [JsonPropertyName("emoji")] public CdnImageLimitsConfiguration Emoji = new CdnImageLimitsConfiguration(); + [JsonPropertyName("sticker")] public CdnImageLimitsConfiguration Sticker = new CdnImageLimitsConfiguration(); + [JsonPropertyName("banner")] public CdnImageLimitsConfiguration Banner = new CdnImageLimitsConfiguration(); + [JsonPropertyName("splash")] public CdnImageLimitsConfiguration Splash = new CdnImageLimitsConfiguration(); + [JsonPropertyName("avatar")] public CdnImageLimitsConfiguration Avatar = new CdnImageLimitsConfiguration(); + [JsonPropertyName("discoverySplash")] public CdnImageLimitsConfiguration DiscoverySplash = new CdnImageLimitsConfiguration(); + [JsonPropertyName("appIcon")] public CdnImageLimitsConfiguration AppIcon = new CdnImageLimitsConfiguration(); + [JsonPropertyName("discoverSplash")] public CdnImageLimitsConfiguration DiscoverSplash = new CdnImageLimitsConfiguration(); //what even is this? + [JsonPropertyName("teamIcon")] public CdnImageLimitsConfiguration TeamIcon = new CdnImageLimitsConfiguration(); + [JsonPropertyName("channelIcon")] public CdnImageLimitsConfiguration ChannelIcon = new CdnImageLimitsConfiguration(); // is this even used? + [JsonPropertyName("guildAvatar")] public CdnImageLimitsConfiguration GuildAvatar = new CdnImageLimitsConfiguration(); +} + +public class CdnImageLimitsConfiguration { + [JsonPropertyName("maxHeight")] public int MaxHeight = 8192; + [JsonPropertyName("maxWidth")] public int MaxWidth = 8192; + + [JsonPropertyName("maxSize")] public int MaxSize = 10 * 1024 * 1024; // 10 MB + + // "always" | "never" | "premium" + [JsonPropertyName("allowAnimated")] public string AllowAnimated = "always"; +} \ No newline at end of file diff --git a/extra/admin-api/Utilities/Spacebar.AdminApi.TestClient/Pages/ServerConfig.razor b/extra/admin-api/Utilities/Spacebar.AdminApi.TestClient/Pages/ServerConfig.razor new file mode 100644
index 00000000..7a83bd52 --- /dev/null +++ b/extra/admin-api/Utilities/Spacebar.AdminApi.TestClient/Pages/ServerConfig.razor
@@ -0,0 +1,26 @@ +@page "/ServerConfig" +@inject Config Config +@using System.Net.Http.Headers +@using System.Text.Json +@using Spacebar.AdminApi.TestClient.Services +@using Spacebar.ConfigModel.Extensions +<h3>Server Config</h3> +@if (CurrentServerConfig is null) { + <p>Loading server config...</p> +} else { + <pre>@JsonSerializer.Serialize(CurrentServerConfig, new JsonSerializerOptions { WriteIndented = true })</pre> +} + +@code { + + private Spacebar.ConfigModel.ServerConfiguration? CurrentServerConfig { get; set; } = new(); + + protected override async Task OnInitializedAsync() { + var hc = new StreamingHttpClient(); + hc.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Config.AccessToken); + var cfgKv = await hc.GetFromJsonAsync<Dictionary<string, string?>>($"{Config.AdminUrl}/_spacebar/admin/config"); + var cfg = cfgKv.ToNestedJsonObject(); + CurrentServerConfig = cfg.Deserialize<Spacebar.ConfigModel.ServerConfiguration>(); + } + +} \ No newline at end of file