diff --git a/extra/admin-api/Interop/Spacebar.Interop.Authentication/SpacebarAuthenticationService.cs b/extra/admin-api/Interop/Spacebar.Interop.Authentication/SpacebarAuthenticationService.cs
index 46ae248f..ffd6c4fa 100644
--- a/extra/admin-api/Interop/Spacebar.Interop.Authentication/SpacebarAuthenticationService.cs
+++ b/extra/admin-api/Interop/Spacebar.Interop.Authentication/SpacebarAuthenticationService.cs
@@ -53,7 +53,7 @@ public class SpacebarAuthenticationService(ILogger<SpacebarAuthenticationService
async () => {
var uid = config.OverrideUid ?? res?.ClaimsIdentity.Claims.First(x => x.Type == "id").Value;
if (string.IsNullOrWhiteSpace(uid)) throw new InvalidOperationException("No user ID specified, is the access token valid?");
- return await db.Users.FindAsync(uid) ?? throw new InvalidOperationException();
+ return await db.Users.FindAsync(long.Parse(uid)) ?? throw new InvalidOperationException();
},
config.AuthCacheExpiry);
}
@@ -64,7 +64,7 @@ public class SpacebarAuthenticationService(ILogger<SpacebarAuthenticationService
async () => {
var did = config.OverrideDid ?? res?.ClaimsIdentity.Claims.First(x => x.Type == "did").Value;
if (string.IsNullOrWhiteSpace(did)) throw new InvalidOperationException("No device ID specified, is the access token valid?");
- return await db.Sessions.FindAsync(did) ?? throw new InvalidOperationException();
+ return await db.Sessions.FindAsync(long.Parse(did)) ?? throw new InvalidOperationException();
},
config.AuthCacheExpiry);
}
diff --git a/extra/admin-api/Models/Spacebar.Models.AdminApi/DiscoverableGuildModel.cs b/extra/admin-api/Models/Spacebar.Models.AdminApi/DiscoverableGuildModel.cs
index fc75f7a0..6c529b41 100644
--- a/extra/admin-api/Models/Spacebar.Models.AdminApi/DiscoverableGuildModel.cs
+++ b/extra/admin-api/Models/Spacebar.Models.AdminApi/DiscoverableGuildModel.cs
@@ -120,8 +120,8 @@ public class DiscoverableGuildModel {
[JsonPropertyName("premium_progress_bar_enabled")]
public bool? PremiumProgressBarEnabled { get; set; }
- [JsonPropertyName("channel_ordering")]
- public List<string> ChannelOrdering { get; set; }
+ [JsonPropertyName("channel_ordering"), JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
+ public List<long> ChannelOrdering { get; set; }
[JsonPropertyName("discovery_weight")]
public int DiscoveryWeight { get; set; }
diff --git a/extra/admin-api/Models/Spacebar.Models.AdminApi/GuildModel.cs b/extra/admin-api/Models/Spacebar.Models.AdminApi/GuildModel.cs
index f4cad9d7..0a2182a7 100644
--- a/extra/admin-api/Models/Spacebar.Models.AdminApi/GuildModel.cs
+++ b/extra/admin-api/Models/Spacebar.Models.AdminApi/GuildModel.cs
@@ -15,7 +15,7 @@ public class GuildModel {
public string? Description { get; set; }
public string? DiscoverySplash { get; set; }
public int? ExplicitContentFilter { get; set; }
- public string Features { get; set; } = null!;
+ public List<string> Features { get; set; } = null!;
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
public long? PrimaryCategoryId { get; set; }
@@ -66,7 +66,9 @@ public class GuildModel {
public bool Nsfw { get; set; }
public string? Parent { get; set; }
public bool? PremiumProgressBarEnabled { get; set; }
- public string ChannelOrdering { get; set; } = null!;
+
+ [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
+ public List<long> ChannelOrdering { get; set; } = null!;
public int ChannelCount { get; set; }
public int RoleCount { get; set; }
diff --git a/extra/admin-api/Models/Spacebar.Models.AdminApi/UserModel.cs b/extra/admin-api/Models/Spacebar.Models.AdminApi/UserModel.cs
index 7e259048..acba6a82 100644
--- a/extra/admin-api/Models/Spacebar.Models.AdminApi/UserModel.cs
+++ b/extra/admin-api/Models/Spacebar.Models.AdminApi/UserModel.cs
@@ -11,7 +11,7 @@ public class UserModel {
public string? Avatar { get; set; }
public int? AccentColor { get; set; }
public string? Banner { get; set; }
- public string? ThemeColors { get; set; }
+ public List<int>? ThemeColors { get; set; }
public string? Pronouns { get; set; }
public string? Phone { get; set; }
public bool Desktop { get; set; }
diff --git a/extra/admin-api/Models/Spacebar.Models.Db/Models/Application.cs b/extra/admin-api/Models/Spacebar.Models.Db/Models/Application.cs
index 921f108d..9ee3811f 100644
--- a/extra/admin-api/Models/Spacebar.Models.Db/Models/Application.cs
+++ b/extra/admin-api/Models/Spacebar.Models.Db/Models/Application.cs
@@ -44,8 +44,8 @@ public partial class Application
[Column("flags")]
public int Flags { get; set; }
- [Column("redirect_uris")]
- public string? RedirectUris { get; set; }
+ [Column("redirect_uris", TypeName = "character varying[]")]
+ public List<string>? RedirectUris { get; set; }
[Column("rpc_application_state")]
public int? RpcApplicationState { get; set; }
@@ -71,8 +71,8 @@ public partial class Application
[Column("discovery_eligibility_flags")]
public int? DiscoveryEligibilityFlags { get; set; }
- [Column("tags")]
- public string? Tags { get; set; }
+ [Column("tags", TypeName = "character varying[]")]
+ public List<string>? Tags { get; set; }
[Column("cover_image", TypeName = "character varying")]
public string? CoverImage { get; set; }
diff --git a/extra/admin-api/Models/Spacebar.Models.Db/Models/AutomodRule.cs b/extra/admin-api/Models/Spacebar.Models.Db/Models/AutomodRule.cs
index d0aebfce..8dbb0be1 100644
--- a/extra/admin-api/Models/Spacebar.Models.Db/Models/AutomodRule.cs
+++ b/extra/admin-api/Models/Spacebar.Models.Db/Models/AutomodRule.cs
@@ -20,10 +20,10 @@ public partial class AutomodRule
public int EventType { get; set; }
[Column("exempt_channels")]
- public string ExemptChannels { get; set; } = null!;
+ public List<long> ExemptChannels { get; set; } = null!;
[Column("exempt_roles")]
- public string ExemptRoles { get; set; } = null!;
+ public List<long> ExemptRoles { get; set; } = null!;
[Column("guild_id")]
public long GuildId { get; set; }
diff --git a/extra/admin-api/Models/Spacebar.Models.Db/Models/ConnectedAccount.cs b/extra/admin-api/Models/Spacebar.Models.Db/Models/ConnectedAccount.cs
index 276fb07e..c9aad658 100644
--- a/extra/admin-api/Models/Spacebar.Models.Db/Models/ConnectedAccount.cs
+++ b/extra/admin-api/Models/Spacebar.Models.Db/Models/ConnectedAccount.cs
@@ -40,8 +40,8 @@ public partial class ConnectedAccount
[Column("visibility")]
public int Visibility { get; set; }
- [Column("integrations")]
- public string Integrations { get; set; } = null!;
+ [Column("integrations", TypeName = "character varying[]")]
+ public List<string> Integrations { get; set; } = null!;
[Column("metadata", TypeName = "jsonb")]
public string? Metadata { get; set; }
diff --git a/extra/admin-api/Models/Spacebar.Models.Db/Models/Emoji.cs b/extra/admin-api/Models/Spacebar.Models.Db/Models/Emoji.cs
index e8f92556..04b0ae03 100644
--- a/extra/admin-api/Models/Spacebar.Models.Db/Models/Emoji.cs
+++ b/extra/admin-api/Models/Spacebar.Models.Db/Models/Emoji.cs
@@ -35,10 +35,10 @@ public partial class Emoji
public bool RequireColons { get; set; }
[Column("roles")]
- public string Roles { get; set; } = null!;
+ public List<long> Roles { get; set; } = null!;
[Column("groups")]
- public string? Groups { get; set; }
+ public List<long>? Groups { get; set; }
[ForeignKey("GuildId")]
[InverseProperty("Emojis")]
diff --git a/extra/admin-api/Models/Spacebar.Models.Db/Models/Guild.cs b/extra/admin-api/Models/Spacebar.Models.Db/Models/Guild.cs
index e93b49ad..359caa84 100644
--- a/extra/admin-api/Models/Spacebar.Models.Db/Models/Guild.cs
+++ b/extra/admin-api/Models/Spacebar.Models.Db/Models/Guild.cs
@@ -34,8 +34,8 @@ public partial class Guild
[Column("explicit_content_filter")]
public int? ExplicitContentFilter { get; set; }
- [Column("features")]
- public string Features { get; set; } = null!;
+ [Column("features", TypeName = "character varying[]")]
+ public List<string> Features { get; set; } = null!;
[Column("primary_category_id")]
public long? PrimaryCategoryId { get; set; }
@@ -128,7 +128,7 @@ public partial class Guild
public bool? PremiumProgressBarEnabled { get; set; }
[Column("channel_ordering")]
- public string ChannelOrdering { get; set; } = null!;
+ public List<long> ChannelOrdering { get; set; } = null!;
[Column("discovery_weight")]
public int DiscoveryWeight { get; set; }
diff --git a/extra/admin-api/Models/Spacebar.Models.Db/Models/Member.cs b/extra/admin-api/Models/Spacebar.Models.Db/Models/Member.cs
index d8311ca5..3d2a3e71 100644
--- a/extra/admin-api/Models/Spacebar.Models.Db/Models/Member.cs
+++ b/extra/admin-api/Models/Spacebar.Models.Db/Models/Member.cs
@@ -57,7 +57,7 @@ public partial class Member
public string Bio { get; set; } = null!;
[Column("theme_colors")]
- public string? ThemeColors { get; set; }
+ public List<int>? ThemeColors { get; set; }
[Column("pronouns", TypeName = "character varying")]
public string? Pronouns { get; set; }
diff --git a/extra/admin-api/Models/Spacebar.Models.Db/Models/TeamMember.cs b/extra/admin-api/Models/Spacebar.Models.Db/Models/TeamMember.cs
index c626e859..81ec04d7 100644
--- a/extra/admin-api/Models/Spacebar.Models.Db/Models/TeamMember.cs
+++ b/extra/admin-api/Models/Spacebar.Models.Db/Models/TeamMember.cs
@@ -16,8 +16,8 @@ public partial class TeamMember
[Column("membership_state")]
public int MembershipState { get; set; }
- [Column("permissions")]
- public string Permissions { get; set; } = null!;
+ [Column("permissions", TypeName = "character varying[]")]
+ public List<string> Permissions { get; set; } = null!;
[Column("team_id")]
public long? TeamId { get; set; }
diff --git a/extra/admin-api/Models/Spacebar.Models.Db/Models/User.cs b/extra/admin-api/Models/Spacebar.Models.Db/Models/User.cs
index ed0eaccb..e1005db2 100644
--- a/extra/admin-api/Models/Spacebar.Models.Db/Models/User.cs
+++ b/extra/admin-api/Models/Spacebar.Models.Db/Models/User.cs
@@ -30,7 +30,7 @@ public partial class User
public string? Banner { get; set; }
[Column("theme_colors")]
- public string? ThemeColors { get; set; }
+ public List<int>? ThemeColors { get; set; }
[Column("pronouns", TypeName = "character varying")]
public string? Pronouns { get; set; }
@@ -107,8 +107,8 @@ public partial class User
[Column("data", TypeName = "jsonb")]
public string Data { get; set; } = null!;
- [Column("fingerprints")]
- public string Fingerprints { get; set; } = null!;
+ [Column("fingerprints", TypeName = "character varying[]")]
+ public List<string> Fingerprints { get; set; } = null!;
[Column("settingsIndex")]
public int? SettingsIndex { get; set; }
@@ -117,7 +117,7 @@ public partial class User
public bool WebauthnEnabled { get; set; }
[Column("badge_ids")]
- public string? BadgeIds { get; set; }
+ public List<long>? BadgeIds { get; set; }
[Column("avatar_decoration_data", TypeName = "jsonb")]
public string? AvatarDecorationData { get; set; }
diff --git a/extra/admin-api/Models/Spacebar.Models.Db/Spacebar.Models.Db.csproj b/extra/admin-api/Models/Spacebar.Models.Db/Spacebar.Models.Db.csproj
index e987a369..2d1dcaf5 100644
--- a/extra/admin-api/Models/Spacebar.Models.Db/Spacebar.Models.Db.csproj
+++ b/extra/admin-api/Models/Spacebar.Models.Db/Spacebar.Models.Db.csproj
@@ -7,7 +7,8 @@
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="*" />
+ <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="*" />
</ItemGroup>
</Project>
diff --git a/extra/admin-api/Models/Spacebar.Models.Db/deps.json b/extra/admin-api/Models/Spacebar.Models.Db/deps.json
index 79f44dd4..53b3a662 100644
--- a/extra/admin-api/Models/Spacebar.Models.Db/deps.json
+++ b/extra/admin-api/Models/Spacebar.Models.Db/deps.json
@@ -1,28 +1,98 @@
[
{
+ "pname": "Humanizer.Core",
+ "version": "2.14.1",
+ "hash": "sha256-EXvojddPu+9JKgOG9NSQgUTfWq1RpOYw7adxDPKDJ6o="
+ },
+ {
+ "pname": "Microsoft.Build.Framework",
+ "version": "17.11.31",
+ "hash": "sha256-YS4oASrmC5dmZrx5JPS7SfKmUpIJErlUpVDsU3VrfFE="
+ },
+ {
+ "pname": "Microsoft.Build.Framework",
+ "version": "18.0.2",
+ "hash": "sha256-fO31KAdDs2J0RUYD1ov9UB3ucsbALan7K0YdWW+yg7A="
+ },
+ {
+ "pname": "Microsoft.CodeAnalysis.Analyzers",
+ "version": "3.11.0",
+ "hash": "sha256-hQ2l6E6PO4m7i+ZsfFlEx+93UsLPo4IY3wDkNG11/Sw="
+ },
+ {
+ "pname": "Microsoft.CodeAnalysis.Common",
+ "version": "5.0.0",
+ "hash": "sha256-g4ALvBSNyHEmSb1l5TFtWW7zEkiRmhqLx4XWZu9sr2U="
+ },
+ {
+ "pname": "Microsoft.CodeAnalysis.CSharp",
+ "version": "5.0.0",
+ "hash": "sha256-ctBCkQGFpH/xT5rRE3xibu9YxPD108RuC4a4Z25koG8="
+ },
+ {
+ "pname": "Microsoft.CodeAnalysis.CSharp.Workspaces",
+ "version": "5.0.0",
+ "hash": "sha256-yWVcLt/f2CouOfFy966glGdtSFy+RcgrU1dd9UtlL/Q="
+ },
+ {
+ "pname": "Microsoft.CodeAnalysis.Workspaces.Common",
+ "version": "5.0.0",
+ "hash": "sha256-Bir5e1gEhgQQ6upQmVKQHAKLRfenAu60DAzNupNnZsQ="
+ },
+ {
+ "pname": "Microsoft.CodeAnalysis.Workspaces.MSBuild",
+ "version": "5.0.0",
+ "hash": "sha256-+58+iqTayTiE0pDaog1U8mjaDA8bNNDLA8gjCQZZudo="
+ },
+ {
"pname": "Microsoft.EntityFrameworkCore",
"version": "10.0.4",
"hash": "sha256-V3Vwl1MtVMRTPo7a9lAgs6UaeMnFV3eEsKnLyPaPMHA="
},
{
+ "pname": "Microsoft.EntityFrameworkCore",
+ "version": "10.0.8",
+ "hash": "sha256-NvDbNeCIHHslXfHtoyxedtJ8BYcSjsvmKz0rc0jNhN0="
+ },
+ {
"pname": "Microsoft.EntityFrameworkCore.Abstractions",
"version": "10.0.4",
"hash": "sha256-so4y7Wrp/oWhQ7wd1rK9ha9GtPme1l5H8SrQz7sf8MQ="
},
{
+ "pname": "Microsoft.EntityFrameworkCore.Abstractions",
+ "version": "10.0.8",
+ "hash": "sha256-vgjR3wT9QvR4LYgy4BaeIQlajW7KWhLAwHgXsyNxioc="
+ },
+ {
"pname": "Microsoft.EntityFrameworkCore.Analyzers",
"version": "10.0.4",
"hash": "sha256-Wed75M4RdQ7bCUWSc+q/0YqL6R5CrIZ2X0t/LpU7ZZA="
},
{
+ "pname": "Microsoft.EntityFrameworkCore.Analyzers",
+ "version": "10.0.8",
+ "hash": "sha256-R2rH/R7Us1vbH4JWKvj364HKYXEe2b+7jXcI3C1d7v4="
+ },
+ {
+ "pname": "Microsoft.EntityFrameworkCore.Design",
+ "version": "10.0.8",
+ "hash": "sha256-QEb8xScQ6uimJwbqdaZA8WwL2pirmX80fi3BR6Swoeg="
+ },
+ {
"pname": "Microsoft.EntityFrameworkCore.Relational",
"version": "10.0.4",
"hash": "sha256-WwGoCwNxDXyqfBvUX9fGa/6X+yiDBuE7hf3csU78+Os="
},
{
+ "pname": "Microsoft.EntityFrameworkCore.Relational",
+ "version": "10.0.8",
+ "hash": "sha256-dcvuQ0ga+TI2G6J31aOClH9hejp2/AftSJYNcRI3USo="
+ },
+ {
"pname": "Microsoft.Extensions.Caching.Abstractions",
- "version": "10.0.4",
- "hash": "sha256-/vLXWvT42HQAm/JLjWGeFo9AvLn/mu4nCNjabm+wABE="
+ "version": "10.0.8",
+ "hash": "sha256-xn2gR3NHo4+XBZIqrHXo8QlYI7AnhA51gtlgSqrPpQ0="
},
{
"pname": "Microsoft.Extensions.Caching.Memory",
@@ -30,24 +100,39 @@
"hash": "sha256-+0sK/vSyB4KFC9kliECROfK1WaiWwlRrhLpi03pT+3w="
},
{
+ "pname": "Microsoft.Extensions.Caching.Memory",
+ "version": "10.0.8",
+ "hash": "sha256-41uLtpgrA7S9WF3sIR9JVi90Kmmf6iy8mjmNTD9MQkU="
+ },
+ {
"pname": "Microsoft.Extensions.Configuration.Abstractions",
- "version": "10.0.4",
- "hash": "sha256-bvEQLGSOpJHKdPD6kd59IIi4x57lKapVMgOORtcjJPs="
+ "version": "10.0.8",
+ "hash": "sha256-M0coNqsIolazd8E0jU8uf43X7Yw5Nf3+sXZQXX/xhq8="
},
{
"pname": "Microsoft.Extensions.DependencyInjection",
- "version": "10.0.4",
- "hash": "sha256-hbpKNzN0KIszhlpM5iAT/V3B7QRs3FGTZI9Wq/cYc1A="
+ "version": "10.0.8",
+ "hash": "sha256-eKex/vpm5A4o2WV6sJyjqKPydWhekJFO6wrH0V7RyBY="
+ },
+ {
+ "pname": "Microsoft.Extensions.DependencyInjection",
+ "version": "9.0.0",
+ "hash": "sha256-dAH52PPlTLn7X+1aI/7npdrDzMEFPMXRv4isV1a+14k="
},
{
"pname": "Microsoft.Extensions.DependencyInjection.Abstractions",
- "version": "10.0.0",
- "hash": "sha256-9iodXP39YqgxomnOPOxd/mzbG0JfOSXzFoNU3omT2Ps="
+ "version": "10.0.8",
+ "hash": "sha256-HV30fu+lF/GYkeVP+Yq/EU1FzgdMqwqlepCpvxUgugE="
},
{
"pname": "Microsoft.Extensions.DependencyInjection.Abstractions",
- "version": "10.0.4",
- "hash": "sha256-0QhVYjk9Cxy6NFef9VKftGmscTZnvcD1bhBQoXz3mwA="
+ "version": "9.0.0",
+ "hash": "sha256-CncVwkKZ5CsIG2O0+OM9qXuYXh3p6UGyueTHSLDVL+c="
+ },
+ {
+ "pname": "Microsoft.Extensions.DependencyModel",
+ "version": "10.0.8",
+ "hash": "sha256-YX986Og+47sJnNonmoZCqa54HCaZhJ8fJl45qeRaaUQ="
},
{
"pname": "Microsoft.Extensions.Logging",
@@ -55,24 +140,64 @@
"hash": "sha256-eneXBu83dGBiWMFabheGFPYiZJQ+WMewG6bTs2oJ7RA="
},
{
+ "pname": "Microsoft.Extensions.Logging",
+ "version": "10.0.8",
+ "hash": "sha256-wcnZWJDQGe6iTd7SIvcbyZLO+Lyc3zCKWlYYP8ovA44="
+ },
+ {
+ "pname": "Microsoft.Extensions.Logging",
+ "version": "9.0.0",
+ "hash": "sha256-kR16c+N8nQrWeYLajqnXPg7RiXjZMSFLnKLEs4VfjcM="
+ },
+ {
"pname": "Microsoft.Extensions.Logging.Abstractions",
"version": "10.0.0",
"hash": "sha256-BnhgGZc01HwTSxogavq7Ueq4V7iMA3wPnbfRwQ4RhGk="
},
{
"pname": "Microsoft.Extensions.Logging.Abstractions",
- "version": "10.0.4",
- "hash": "sha256-dvBRBgEf4Bw9NW2J2XDlEeJw2TNhJ+6gV98dPE13/J0="
+ "version": "10.0.8",
+ "hash": "sha256-VruWNhGycjxU2+BxiE++Aw2Tzv50lARcslDp66ImCDE="
+ },
+ {
+ "pname": "Microsoft.Extensions.Logging.Abstractions",
+ "version": "9.0.0",
+ "hash": "sha256-iBTs9twjWXFeERt4CErkIIcoJZU1jrd1RWCI8V5j7KU="
},
{
"pname": "Microsoft.Extensions.Options",
- "version": "10.0.4",
- "hash": "sha256-ybyUtpSs/irdarkVjsGhqDcj0w8TNUgh0Kp0j3EVfIA="
+ "version": "10.0.8",
+ "hash": "sha256-KHcgAMsOPgjK0ly34mAt3/1hPA4XDSltXUNrEjSNnh8="
+ },
+ {
+ "pname": "Microsoft.Extensions.Options",
+ "version": "9.0.0",
+ "hash": "sha256-DT5euAQY/ItB5LPI8WIp6Dnd0lSvBRP35vFkOXC68ck="
},
{
"pname": "Microsoft.Extensions.Primitives",
- "version": "10.0.4",
- "hash": "sha256-ePpEFzrKQbEMY6Kh/xyxKHq6txNru62Vh4LVZO5Rrvg="
+ "version": "10.0.8",
+ "hash": "sha256-LJFzI1nODfakvP3owQn8xwVKliRxIYs6nl19xAbxKOc="
+ },
+ {
+ "pname": "Microsoft.Extensions.Primitives",
+ "version": "9.0.0",
+ "hash": "sha256-ZNLusK1CRuq5BZYZMDqaz04PIKScE2Z7sS2tehU7EJs="
+ },
+ {
+ "pname": "Microsoft.VisualStudio.SolutionPersistence",
+ "version": "1.0.52",
+ "hash": "sha256-KZGPtOXe6Hv8RrkcsgoLKTRyaCScIpQEa2NhNB3iOXw="
+ },
+ {
+ "pname": "Mono.TextTemplating",
+ "version": "3.0.0",
+ "hash": "sha256-VlgGDvgNZb7MeBbIZ4DE2Nn/j2aD9k6XqNHnASUSDr0="
+ },
+ {
+ "pname": "Newtonsoft.Json",
+ "version": "13.0.3",
+ "hash": "sha256-hy/BieY4qxBWVVsDqqOPaLy1QobiIapkbrESm6v2PHc="
},
{
"pname": "Npgsql",
@@ -83,5 +208,40 @@
"pname": "Npgsql.EntityFrameworkCore.PostgreSQL",
"version": "10.0.1",
"hash": "sha256-G5WmWoc02gHTsdBLXESFQ5eMV+liwiO8YjzFKg4NDEk="
+ },
+ {
+ "pname": "System.CodeDom",
+ "version": "6.0.0",
+ "hash": "sha256-uPetUFZyHfxjScu5x4agjk9pIhbCkt5rG4Axj25npcQ="
+ },
+ {
+ "pname": "System.Composition",
+ "version": "9.0.0",
+ "hash": "sha256-FehOkQ2u1p8mQ0/wn3cZ+24HjhTLdck8VZYWA1CcgbM="
+ },
+ {
+ "pname": "System.Composition.AttributedModel",
+ "version": "9.0.0",
+ "hash": "sha256-a7y7H6zj+kmYkllNHA402DoVfY9IaqC3Ooys8Vzl24M="
+ },
+ {
+ "pname": "System.Composition.Convention",
+ "version": "9.0.0",
+ "hash": "sha256-tw4vE5JRQ60ubTZBbxoMPhtjOQCC3XoDFUH7NHO7o8U="
+ },
+ {
+ "pname": "System.Composition.Hosting",
+ "version": "9.0.0",
+ "hash": "sha256-oOxU+DPEEfMCuNLgW6wSkZp0JY5gYt44FJNnWt+967s="
+ },
+ {
+ "pname": "System.Composition.Runtime",
+ "version": "9.0.0",
+ "hash": "sha256-AyIe+di1TqwUBbSJ/sJ8Q8tzsnTN+VBdJw4K8xZz43s="
+ },
+ {
+ "pname": "System.Composition.TypedParts",
+ "version": "9.0.0",
+ "hash": "sha256-F5fpTUs3Rr7yP/NyIzr+Xn5NdTXXp8rrjBnF9UBBUog="
}
]
diff --git a/extra/admin-api/Spacebar.AdminApi/Controllers/DiscoveryController.cs b/extra/admin-api/Spacebar.AdminApi/Controllers/DiscoveryController.cs
index acc27c20..4c466acb 100644
--- a/extra/admin-api/Spacebar.AdminApi/Controllers/DiscoveryController.cs
+++ b/extra/admin-api/Spacebar.AdminApi/Controllers/DiscoveryController.cs
@@ -29,7 +29,7 @@ public class GuildDiscoveryController(
await foreach (var guild in discoverableGuilds.AsAsyncEnumerable()) {
yield return new DiscoverableGuildModel() {
Id = guild.Id,
- Features = guild.Features.Split(",").ToList(),
+ Features = guild.Features,
Banner = guild.Banner,
DiscoveryExcluded = guild.DiscoveryExcluded,
DiscoveryWeight = guild.DiscoveryWeight,
@@ -38,7 +38,7 @@ public class GuildDiscoveryController(
SystemChannelFlags = guild.SystemChannelFlags,
AfkChannelId = guild.AfkChannelId,
AfkTimeout = guild.AfkTimeout,
- ChannelOrdering = guild.ChannelOrdering.Split(",").ToList(),
+ ChannelOrdering = guild.ChannelOrdering,
DefaultMessageNotifications = guild.DefaultMessageNotifications,
Description = guild.Description,
DiscoverySplash = guild.DiscoverySplash,
@@ -86,7 +86,7 @@ public class GuildDiscoveryController(
var guild = await discoverableGuilds.SingleAsync();
return new DiscoverableGuildModel() {
Id = guild.Id,
- Features = guild.Features.Split(",").ToList(),
+ Features = guild.Features,
Banner = guild.Banner,
DiscoveryExcluded = guild.DiscoveryExcluded,
DiscoveryWeight = guild.DiscoveryWeight,
@@ -95,7 +95,7 @@ public class GuildDiscoveryController(
SystemChannelFlags = guild.SystemChannelFlags,
AfkChannelId = guild.AfkChannelId,
AfkTimeout = guild.AfkTimeout,
- ChannelOrdering = guild.ChannelOrdering.Split(",").ToList(),
+ ChannelOrdering = guild.ChannelOrdering,
DefaultMessageNotifications = guild.DefaultMessageNotifications,
Description = guild.Description,
DiscoverySplash = guild.DiscoverySplash,
@@ -152,7 +152,7 @@ public class GuildDiscoveryController(
return new DiscoverableGuildModel() {
Id = guild.Id,
- Features = guild.Features.Split(",").ToList(),
+ Features = guild.Features,
Banner = guild.Banner,
DiscoveryExcluded = guild.DiscoveryExcluded,
DiscoveryWeight = guild.DiscoveryWeight,
@@ -161,7 +161,7 @@ public class GuildDiscoveryController(
SystemChannelFlags = guild.SystemChannelFlags,
AfkChannelId = guild.AfkChannelId,
AfkTimeout = guild.AfkTimeout,
- ChannelOrdering = guild.ChannelOrdering.Split(",").ToList(),
+ ChannelOrdering = guild.ChannelOrdering,
DefaultMessageNotifications = guild.DefaultMessageNotifications,
Description = guild.Description,
DiscoverySplash = guild.DiscoverySplash,
diff --git a/extra/admin-api/Spacebar.AdminApi/Controllers/UserController.cs b/extra/admin-api/Spacebar.AdminApi/Controllers/UserController.cs
index 5b76c72d..51ec84e4 100644
--- a/extra/admin-api/Spacebar.AdminApi/Controllers/UserController.cs
+++ b/extra/admin-api/Spacebar.AdminApi/Controllers/UserController.cs
@@ -1,3 +1,4 @@
+using System.Linq.Expressions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Spacebar.AdminApi.Extensions;
@@ -25,17 +26,17 @@ public class UserController(
/// </summary>
/// <returns>List of user objects</returns>
[HttpGet]
- public async IAsyncEnumerable<UserModel> Get() {
+ public async IAsyncEnumerable<UserModel> Get([FromQuery] string? orderBy, [FromQuery] bool ascending = false, [FromQuery] int? skip = null, [FromQuery] int? limit = null) {
(await auth.GetCurrentUserAsync(Request)).GetRights().AssertHasAllRights(SpacebarRights.Rights.OPERATOR);
-
- var results = db.Users
+ var query = db.Users
+ .AsNoTracking()
.Include(user => user.ApplicationBotUser)
.Include(user => user.MessageAuthors)
.Include(user => user.Sessions)
.Include(user => user.Templates)
.Include(user => user.VoiceStates)
.Include(user => user.Guilds)
- .AsAsyncEnumerable().Select(x => new UserModel {
+ .Select(x => new UserModel {
Id = x.Id,
Username = x.Username,
Discriminator = x.Discriminator,
@@ -74,7 +75,53 @@ public class UserController(
OwnedGuildCount = x.Guilds.Count(g => g.OwnerId == x.Id)
});
- await foreach (var user in results) {
+ if (!string.IsNullOrWhiteSpace(orderBy)) {
+ query = orderBy switch {
+ "id" => query.OrderByDescending(x => x.Id),
+ "username" => query.OrderByDescending(x => x.Username),
+ "discriminator" => query.OrderByDescending(x => x.Discriminator),
+ "avatar" => query.OrderByDescending(x => x.Avatar),
+ "accentColor" => query.OrderByDescending(x => x.AccentColor),
+ "banner" => query.OrderByDescending(x => x.Banner),
+ "themeColors" => query.OrderByDescending(x => x.ThemeColors),
+ "pronouns" => query.OrderByDescending(x => x.Pronouns),
+ "phone" => query.OrderByDescending(x => x.Phone),
+ "desktop" => query.OrderByDescending(x => x.Desktop),
+ "mobile" => query.OrderByDescending(x => x.Mobile),
+ "premium" => query.OrderByDescending(x => x.Premium),
+ "premiumType" => query.OrderByDescending(x => x.PremiumType),
+ "bot" => query.OrderByDescending(x => x.Bot),
+ "bio" => query.OrderByDescending(x => x.Bio),
+ "system" => query.OrderByDescending(x => x.System),
+ "nsfwAllowed" => query.OrderByDescending(x => x.NsfwAllowed),
+ "mfaEnabled" => query.OrderByDescending(x => x.MfaEnabled),
+ "webauthnEnabled" => query.OrderByDescending(x => x.WebauthnEnabled),
+ "createdAt" => query.OrderByDescending(x => x.CreatedAt),
+ "premiumSince" => query.OrderByDescending(x => x.PremiumSince),
+ "verified" => query.OrderByDescending(x => x.Verified),
+ "disabled" => query.OrderByDescending(x => x.Disabled),
+ "deleted" => query.OrderByDescending(x => x.Deleted),
+ "email" => query.OrderByDescending(x => x.Email),
+ "flags" => query.OrderByDescending(x => x.Flags),
+ "publicFlags" => query.OrderByDescending(x => x.PublicFlags),
+ "rights" => query.OrderByDescending(x => x.Rights),
+ "applicationBotUser" => query.OrderByDescending(x => x.ApplicationBotUser),
+ "connectedAccounts" => query.OrderByDescending(x => x.ConnectedAccounts),
+ "messageCount" => query.OrderByDescending(x => x.MessageCount),
+ "sessionCount" => query.OrderByDescending(x => x.SessionCount),
+ "templateCount" => query.OrderByDescending(x => x.TemplateCount),
+ "voiceStateCount" => query.OrderByDescending(x => x.VoiceStateCount),
+ "guildCount" => query.OrderByDescending(x => x.GuildCount),
+ "ownedGuildCount" => query.OrderByDescending(x => x.OwnedGuildCount),
+ _ => throw new Exception("orderBy is not oneOf(id)")
+ };
+ if (ascending) query = query.Reverse();
+ }
+
+ if (skip.HasValue) query = query.Skip(skip.Value);
+ if (limit.HasValue) query = query.Take(limit.Value);
+
+ await foreach (var user in query.AsAsyncEnumerable()) {
yield return user;
}
}
@@ -170,7 +217,7 @@ public class UserController(
yield return new("STATS",
new {
total_messages = messages.Count(), total_channels = channels.Count,
- messages_per_channel = channels.ToDictionary(c => c.ChannelId!, c => messages.Count(m => m.ChannelId == c.ChannelId))
+ messages_per_channel = channels.ToDictionary(c => c.ChannelId!.ToString(), c => messages.Count(m => m.ChannelId == c.ChannelId))
});
if (messages.Any()) {
var results = channels
@@ -190,7 +237,7 @@ public class UserController(
// [HttpGet("{id}/Dms")]
// public async IEnumerable<object> GetDmsAsync(string userId) {
- // yield break; // TODO
+ // yield break; // TODO
// }
private async IAsyncEnumerable<AsyncActionResult> DeleteMessagesForChannel(
@@ -206,15 +253,15 @@ public class UserController(
var remaining = messagesInChannel;
while (true) {
var messageIds = _db.Database.SqlQuery<long>($"""
- DELETE FROM messages
- WHERE id IN (
- SELECT id FROM messages
- WHERE author_id = {authorId}
- AND channel_id = {channelId}
- AND guild_id = {guildId}
- LIMIT {messageDeleteChunkSize}
- ) RETURNING id;
- """).ToList();
+ DELETE FROM messages
+ WHERE id IN (
+ SELECT id FROM messages
+ WHERE author_id = {authorId}
+ AND channel_id = {channelId}
+ AND guild_id = {guildId}
+ LIMIT {messageDeleteChunkSize}
+ ) RETURNING id;
+ """).ToList();
if (messageIds.Count == 0) {
break;
}
diff --git a/extra/admin-api/Spacebar.AdminApi/Middleware/AuthenticationMiddleware.cs b/extra/admin-api/Spacebar.AdminApi/Middleware/AuthenticationMiddleware.cs
index 484859ed..2ee476f6 100644
--- a/extra/admin-api/Spacebar.AdminApi/Middleware/AuthenticationMiddleware.cs
+++ b/extra/admin-api/Spacebar.AdminApi/Middleware/AuthenticationMiddleware.cs
@@ -1,17 +1,28 @@
+using Microsoft.IdentityModel.Tokens;
using Spacebar.Interop.Authentication;
using Spacebar.Interop.Authentication.AspNetCore;
using Spacebar.Models.Db.Models;
namespace Spacebar.AdminApi.Middleware;
-public class AuthenticationMiddleware(SpacebarAspNetAuthenticationService authService, SpacebarAuthenticationConfiguration config, RequestDelegate next) {
+public class AuthenticationMiddleware(
+ ILogger<AuthenticationMiddleware> logger,
+ SpacebarAspNetAuthenticationService authService,
+ SpacebarAuthenticationConfiguration config,
+ RequestDelegate next) {
public async Task InvokeAsync(HttpContext context, IServiceProvider sp) {
if (context.Request.Path.StartsWithSegments("/ping") || config.DisableAuthentication) {
await next(context);
return;
}
- var res = await authService.ValidateTokenAsync(context.Request);
+ TokenValidationResult? res = null;
+ try {
+ await authService.ValidateTokenAsync(context.Request);
+ }
+ catch (Exception e) {
+ logger.LogError("Failed to validate access token: {e}", e);
+ }
if (!(res?.IsValid ?? false)) {
context.Response.StatusCode = 401;
@@ -19,16 +30,25 @@ public class AuthenticationMiddleware(SpacebarAspNetAuthenticationService authSe
return;
}
- User user = await authService.GetCurrentUserAsync(context.Request);
- if (user.Disabled) {
- context.Response.StatusCode = 403;
- await context.Response.WriteAsync("User is disabled");
- return;
- }
+ try {
+ User user = await authService.GetCurrentUserAsync(context.Request);
+ if (user.Disabled) {
+ context.Response.StatusCode = 403;
+ await context.Response.WriteAsync("User is disabled");
+ return;
+ }
- if (user.Deleted) {
- context.Response.StatusCode = 403;
- await context.Response.WriteAsync("User is deleted");
+ if (user.Deleted) {
+ context.Response.StatusCode = 403;
+ await context.Response.WriteAsync("User is deleted");
+ return;
+ }
+ }
+ catch (Exception e) {
+ logger.LogError("Failed to query user: {e}", e);
+
+ context.Response.StatusCode = 412;
+ await context.Response.WriteAsync("Failed to find user");
return;
}
|