diff --git a/Foxnouns.Backend/Controllers/DeleteUserController.cs b/Foxnouns.Backend/Controllers/DeleteUserController.cs
index d1c8e62..b611c35 100644
--- a/Foxnouns.Backend/Controllers/DeleteUserController.cs
+++ b/Foxnouns.Backend/Controllers/DeleteUserController.cs
@@ -1,17 +1,3 @@
-// Copyright (C) 2023-present sam/u1f320 (vulpine.solutions)
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published
-// by the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
using Foxnouns.Backend.Database;
using Foxnouns.Backend.Middleware;
using Microsoft.AspNetCore.Mvc;
diff --git a/Foxnouns.Backend/Controllers/InternalController.cs b/Foxnouns.Backend/Controllers/InternalController.cs
index 3954547..85bc774 100644
--- a/Foxnouns.Backend/Controllers/InternalController.cs
+++ b/Foxnouns.Backend/Controllers/InternalController.cs
@@ -38,8 +38,6 @@ public partial class InternalController(DatabaseContext db) : ControllerBase
{
if (template.StartsWith("api/v2"))
template = template["api/v2".Length..];
- else if (template.StartsWith("api/v1"))
- template = template["api/v1".Length..];
template = PathVarRegex()
.Replace(template, "{id}") // Replace all path variables (almost always IDs) with `{id}`
.Replace("@me", "{id}"); // Also replace hardcoded `@me` with `{id}`
diff --git a/Foxnouns.Backend/Controllers/NotificationsController.cs b/Foxnouns.Backend/Controllers/NotificationsController.cs
index 873344c..f258b3c 100644
--- a/Foxnouns.Backend/Controllers/NotificationsController.cs
+++ b/Foxnouns.Backend/Controllers/NotificationsController.cs
@@ -1,17 +1,3 @@
-// Copyright (C) 2023-present sam/u1f320 (vulpine.solutions)
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published
-// by the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
using Foxnouns.Backend.Database;
using Foxnouns.Backend.Database.Models;
using Foxnouns.Backend.Middleware;
diff --git a/Foxnouns.Backend/Controllers/V1/UsersV1Controller.cs b/Foxnouns.Backend/Controllers/V1/UsersV1Controller.cs
new file mode 100644
index 0000000..e11e490
--- /dev/null
+++ b/Foxnouns.Backend/Controllers/V1/UsersV1Controller.cs
@@ -0,0 +1,16 @@
+using Foxnouns.Backend.Database.Models;
+using Foxnouns.Backend.Services.V1;
+using Microsoft.AspNetCore.Mvc;
+
+namespace Foxnouns.Backend.Controllers.V1;
+
+[Route("/api/v1/users")]
+public class UsersV1Controller(UsersV1Service usersV1Service) : ApiControllerBase
+{
+ [HttpGet("{userRef}")]
+ public async Task GetUserAsync(string userRef, CancellationToken ct = default)
+ {
+ User user = await usersV1Service.ResolveUserAsync(userRef, CurrentToken, ct);
+ return Ok(await usersV1Service.RenderUserAsync(user));
+ }
+}
diff --git a/Foxnouns.Backend/Controllers/V1/V1ReadController.cs b/Foxnouns.Backend/Controllers/V1/V1ReadController.cs
deleted file mode 100644
index 5f69c20..0000000
--- a/Foxnouns.Backend/Controllers/V1/V1ReadController.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (C) 2023-present sam/u1f320 (vulpine.solutions)
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published
-// by the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-using Foxnouns.Backend.Database;
-using Foxnouns.Backend.Database.Models;
-using Foxnouns.Backend.Dto.V1;
-using Foxnouns.Backend.Services.V1;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.EntityFrameworkCore;
-
-namespace Foxnouns.Backend.Controllers.V1;
-
-[Route("/api/v1")]
-public class V1ReadController(
- UsersV1Service usersV1Service,
- MembersV1Service membersV1Service,
- DatabaseContext db
-) : ApiControllerBase
-{
- [HttpGet("users/{userRef}")]
- public async Task GetUserAsync(string userRef, CancellationToken ct = default)
- {
- User user = await usersV1Service.ResolveUserAsync(userRef, CurrentToken, ct);
- return Ok(
- await usersV1Service.RenderUserAsync(
- user,
- CurrentToken,
- renderMembers: true,
- renderFlags: true,
- ct: ct
- )
- );
- }
-
- [HttpGet("members/{id}")]
- public async Task GetMemberAsync(string id, CancellationToken ct = default)
- {
- Member member = await membersV1Service.ResolveMemberAsync(id, ct);
- return Ok(
- await membersV1Service.RenderMemberAsync(
- member,
- CurrentToken,
- renderFlags: true,
- ct: ct
- )
- );
- }
-
- [HttpGet("users/{userRef}/members")]
- public async Task GetUserMembersAsync(
- string userRef,
- CancellationToken ct = default
- )
- {
- User user = await usersV1Service.ResolveUserAsync(userRef, CurrentToken, ct);
- List members = await db
- .Members.Where(m => m.UserId == user.Id)
- .OrderBy(m => m.Name)
- .ToListAsync(ct);
-
- List responses = [];
- foreach (Member member in members)
- {
- responses.Add(
- await membersV1Service.RenderMemberAsync(
- member,
- CurrentToken,
- user,
- renderFlags: true,
- ct: ct
- )
- );
- }
-
- return Ok(responses);
- }
-
- [HttpGet("users/{userRef}/members/{memberRef}")]
- public async Task GetUserMemberAsync(
- string userRef,
- string memberRef,
- CancellationToken ct = default
- )
- {
- Member member = await membersV1Service.ResolveMemberAsync(
- userRef,
- memberRef,
- CurrentToken,
- ct
- );
- return Ok(
- await membersV1Service.RenderMemberAsync(
- member,
- CurrentToken,
- renderFlags: true,
- ct: ct
- )
- );
- }
-}
diff --git a/Foxnouns.Backend/Dto/V1/Member.cs b/Foxnouns.Backend/Dto/V1/Member.cs
deleted file mode 100644
index c745187..0000000
--- a/Foxnouns.Backend/Dto/V1/Member.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (C) 2023-present sam/u1f320 (vulpine.solutions)
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published
-// by the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-// ReSharper disable NotAccessedPositionalProperty.Global
-using Foxnouns.Backend.Database;
-using Newtonsoft.Json;
-
-namespace Foxnouns.Backend.Dto.V1;
-
-public record PartialMember(
- string Id,
- Snowflake IdNew,
- string Sid,
- string Name,
- string? DisplayName,
- string? Bio,
- string? Avatar,
- string[] Links,
- FieldEntry[] Names,
- PronounEntry[] Pronouns
-);
-
-public record MemberResponse(
- string Id,
- Snowflake IdNew,
- string Sid,
- string Name,
- string? DisplayName,
- string? Bio,
- string? Avatar,
- string[] Links,
- FieldEntry[] Names,
- PronounEntry[] Pronouns,
- ProfileField[] Fields,
- PrideFlag[] Flags,
- PartialUser User,
- [property: JsonProperty(NullValueHandling = NullValueHandling.Ignore)] bool? Unlisted
-);
-
-public record PartialUser(
- string Id,
- Snowflake IdNew,
- string Name,
- string? DisplayName,
- string? Avatar,
- Dictionary CustomPreferences
-);
diff --git a/Foxnouns.Backend/Dto/V1/User.cs b/Foxnouns.Backend/Dto/V1/User.cs
index c212d97..eab4c29 100644
--- a/Foxnouns.Backend/Dto/V1/User.cs
+++ b/Foxnouns.Backend/Dto/V1/User.cs
@@ -1,18 +1,3 @@
-// Copyright (C) 2023-present sam/u1f320 (vulpine.solutions)
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published
-// by the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
// ReSharper disable NotAccessedPositionalProperty.Global
using Foxnouns.Backend.Database;
using Foxnouns.Backend.Database.Models;
@@ -36,8 +21,6 @@ public record UserResponse(
FieldEntry[] Names,
PronounEntry[] Pronouns,
ProfileField[] Fields,
- PrideFlag[] Flags,
- PartialMember[] Members,
int? UtcOffset,
Dictionary CustomPreferences
);
@@ -92,5 +75,3 @@ public record PronounEntry(string Pronouns, string? DisplayText, string Status)
))
.ToArray();
}
-
-public record PrideFlag(string Id, Snowflake IdNew, string Hash, string Name, string? Description);
diff --git a/Foxnouns.Backend/Extensions/WebApplicationExtensions.cs b/Foxnouns.Backend/Extensions/WebApplicationExtensions.cs
index 426ec12..86b4a82 100644
--- a/Foxnouns.Backend/Extensions/WebApplicationExtensions.cs
+++ b/Foxnouns.Backend/Extensions/WebApplicationExtensions.cs
@@ -130,8 +130,7 @@ public static class WebApplicationExtensions
.AddTransient()
.AddTransient()
// Legacy services
- .AddScoped()
- .AddScoped();
+ .AddScoped();
if (!config.Logging.EnableMetrics)
services.AddHostedService();
diff --git a/Foxnouns.Backend/Services/V1/MembersV1Service.cs b/Foxnouns.Backend/Services/V1/MembersV1Service.cs
deleted file mode 100644
index 632226c..0000000
--- a/Foxnouns.Backend/Services/V1/MembersV1Service.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (C) 2023-present sam/u1f320 (vulpine.solutions)
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published
-// by the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-using Foxnouns.Backend.Database;
-using Foxnouns.Backend.Database.Models;
-using Foxnouns.Backend.Dto.V1;
-using Microsoft.EntityFrameworkCore;
-using FieldEntry = Foxnouns.Backend.Dto.V1.FieldEntry;
-using PrideFlag = Foxnouns.Backend.Dto.V1.PrideFlag;
-
-namespace Foxnouns.Backend.Services.V1;
-
-public class MembersV1Service(DatabaseContext db, UsersV1Service usersV1Service)
-{
- public async Task ResolveMemberAsync(string id, CancellationToken ct = default)
- {
- Member? member;
- if (Snowflake.TryParse(id, out Snowflake? sf))
- {
- member = await db
- .Members.Include(m => m.User)
- .FirstOrDefaultAsync(m => m.Id == sf && !m.User.Deleted, ct);
- if (member != null)
- return member;
- }
-
- member = await db
- .Members.Include(m => m.User)
- .FirstOrDefaultAsync(m => m.LegacyId == id && !m.User.Deleted, ct);
- if (member != null)
- return member;
-
- throw new ApiError.NotFound("No member with that ID found.", ErrorCode.MemberNotFound);
- }
-
- public async Task ResolveMemberAsync(
- string userRef,
- string memberRef,
- Token? token,
- CancellationToken ct = default
- )
- {
- User user = await usersV1Service.ResolveUserAsync(userRef, token, ct);
-
- Member? member;
- if (Snowflake.TryParse(memberRef, out Snowflake? sf))
- {
- member = await db
- .Members.Include(m => m.User)
- .FirstOrDefaultAsync(m => m.Id == sf && m.UserId == user.Id, ct);
- if (member != null)
- return member;
- }
-
- member = await db
- .Members.Include(m => m.User)
- .FirstOrDefaultAsync(m => m.LegacyId == memberRef && m.UserId == user.Id, ct);
- if (member != null)
- return member;
-
- member = await db
- .Members.Include(m => m.User)
- .FirstOrDefaultAsync(m => m.Name == memberRef && m.UserId == user.Id, ct);
- if (member != null)
- return member;
-
- throw new ApiError.NotFound(
- "No member with that ID or name found.",
- ErrorCode.MemberNotFound
- );
- }
-
- public async Task RenderMemberAsync(
- Member m,
- Token? token = default,
- User? user = null,
- bool renderFlags = true,
- CancellationToken ct = default
- )
- {
- user ??= m.User;
- bool renderUnlisted = m.UserId == token?.UserId;
-
- List flags = renderFlags
- ? await db.MemberFlags.Where(f => f.MemberId == m.Id).OrderBy(f => f.Id).ToListAsync(ct)
- : [];
-
- return new MemberResponse(
- m.LegacyId,
- m.Id,
- m.Sid,
- m.Name,
- m.DisplayName,
- m.Bio,
- m.Avatar,
- m.Links,
- Names: FieldEntry.FromEntries(m.Names, user.CustomPreferences),
- Pronouns: PronounEntry.FromPronouns(m.Pronouns, user.CustomPreferences),
- Fields: ProfileField.FromFields(m.Fields, user.CustomPreferences),
- Flags: flags
- .Where(f => f.PrideFlag.Hash != null)
- .Select(f => new PrideFlag(
- f.PrideFlag.LegacyId,
- f.PrideFlag.Id,
- f.PrideFlag.Hash!,
- f.PrideFlag.Name,
- f.PrideFlag.Description
- ))
- .ToArray(),
- User: UsersV1Service.RenderPartialUser(user),
- Unlisted: renderUnlisted ? m.Unlisted : null
- );
- }
-}
diff --git a/Foxnouns.Backend/Services/V1/UsersV1Service.cs b/Foxnouns.Backend/Services/V1/UsersV1Service.cs
index 34163a6..7492256 100644
--- a/Foxnouns.Backend/Services/V1/UsersV1Service.cs
+++ b/Foxnouns.Backend/Services/V1/UsersV1Service.cs
@@ -1,23 +1,8 @@
-// Copyright (C) 2023-present sam/u1f320 (vulpine.solutions)
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published
-// by the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
using Foxnouns.Backend.Database;
using Foxnouns.Backend.Database.Models;
using Foxnouns.Backend.Dto.V1;
using Microsoft.EntityFrameworkCore;
using FieldEntry = Foxnouns.Backend.Dto.V1.FieldEntry;
-using PrideFlag = Foxnouns.Backend.Dto.V1.PrideFlag;
namespace Foxnouns.Backend.Services.V1;
@@ -64,26 +49,8 @@ public class UsersV1Service(DatabaseContext db)
);
}
- public async Task RenderUserAsync(
- User user,
- Token? token = null,
- bool renderMembers = true,
- bool renderFlags = true,
- CancellationToken ct = default
- )
+ public async Task RenderUserAsync(User user)
{
- bool isSelfUser = user.Id == token?.UserId;
- renderMembers = renderMembers && (isSelfUser || !user.ListHidden);
-
- // Only fetch members if we're rendering members (duh)
- List members = renderMembers
- ? await db.Members.Where(m => m.UserId == user.Id).OrderBy(m => m.Name).ToListAsync(ct)
- : [];
-
- List flags = renderFlags
- ? await db.UserFlags.Where(f => f.UserId == user.Id).OrderBy(f => f.Id).ToListAsync(ct)
- : [];
-
int? utcOffset = null;
if (
user.Timezone != null
@@ -103,67 +70,23 @@ public class UsersV1Service(DatabaseContext db)
user.MemberTitle,
user.Avatar,
user.Links,
- Names: FieldEntry.FromEntries(user.Names, user.CustomPreferences),
- Pronouns: PronounEntry.FromPronouns(user.Pronouns, user.CustomPreferences),
- Fields: ProfileField.FromFields(user.Fields, user.CustomPreferences),
- Flags: flags
- .Where(f => f.PrideFlag.Hash != null)
- .Select(f => new PrideFlag(
- f.PrideFlag.LegacyId,
- f.PrideFlag.Id,
- f.PrideFlag.Hash!,
- f.PrideFlag.Name,
- f.PrideFlag.Description
- ))
- .ToArray(),
- Members: members.Select(m => RenderPartialMember(m, user.CustomPreferences)).ToArray(),
+ FieldEntry.FromEntries(user.Names, user.CustomPreferences),
+ PronounEntry.FromPronouns(user.Pronouns, user.CustomPreferences),
+ ProfileField.FromFields(user.Fields, user.CustomPreferences),
utcOffset,
- CustomPreferences: RenderCustomPreferences(user.CustomPreferences)
- );
- }
-
- private static Dictionary RenderCustomPreferences(
- Dictionary customPreferences
- ) =>
- customPreferences
- .Select(x =>
- (
- x.Value.LegacyId,
- new CustomPreference(
- x.Value.Icon,
- x.Value.Tooltip,
- x.Value.Size,
- x.Value.Muted,
- x.Value.Favourite
+ user.CustomPreferences.Select(x =>
+ (
+ x.Value.LegacyId,
+ new CustomPreference(
+ x.Value.Icon,
+ x.Value.Tooltip,
+ x.Value.Size,
+ x.Value.Muted,
+ x.Value.Favourite
+ )
)
)
- )
- .ToDictionary();
-
- private static PartialMember RenderPartialMember(
- Member m,
- Dictionary customPreferences
- ) =>
- new(
- m.LegacyId,
- m.Id,
- m.Sid,
- m.Name,
- m.DisplayName,
- m.Bio,
- m.Avatar,
- m.Links,
- Names: FieldEntry.FromEntries(m.Names, customPreferences),
- Pronouns: PronounEntry.FromPronouns(m.Pronouns, customPreferences)
- );
-
- public static PartialUser RenderPartialUser(User user) =>
- new(
- user.LegacyId,
- user.Id,
- user.Username,
- user.DisplayName,
- user.Avatar,
- CustomPreferences: RenderCustomPreferences(user.CustomPreferences)
+ .ToDictionary()
);
+ }
}
diff --git a/Foxnouns.Backend/Services/V1/V1Utils.cs b/Foxnouns.Backend/Services/V1/V1Utils.cs
index 2e52316..eb8d9c0 100644
--- a/Foxnouns.Backend/Services/V1/V1Utils.cs
+++ b/Foxnouns.Backend/Services/V1/V1Utils.cs
@@ -1,17 +1,3 @@
-// Copyright (C) 2023-present sam/u1f320 (vulpine.solutions)
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published
-// by the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
using Foxnouns.Backend.Database;
using Foxnouns.Backend.Database.Models;
diff --git a/Foxnouns.Backend/config.example.ini b/Foxnouns.Backend/config.example.ini
index 9c6097e..7522cba 100644
--- a/Foxnouns.Backend/config.example.ini
+++ b/Foxnouns.Backend/config.example.ini
@@ -1,7 +1,7 @@
; The host the server will listen on
Host = localhost
; The port the server will listen on
-Port = 6000
+Port = 5000
; The base *external* URL
BaseUrl = https://pronouns.localhost
; The base URL for media, without a trailing slash. This must be publicly accessible.
diff --git a/Foxnouns.Frontend/.env.example b/Foxnouns.Frontend/.env.example
index 2931832..d79c672 100644
--- a/Foxnouns.Frontend/.env.example
+++ b/Foxnouns.Frontend/.env.example
@@ -1,7 +1,7 @@
-# Example .env file--DO NOT EDIT, copy to .env or .env.local then edit
+# Example .env file--DO NOT EDIT
PUBLIC_LANGUAGE=en
PUBLIC_BASE_URL=https://pronouns.cc
PUBLIC_SHORT_URL=https://prns.cc
PUBLIC_API_BASE=https://pronouns.cc/api
PRIVATE_API_HOST=http://localhost:5003/api
-PRIVATE_INTERNAL_API_HOST=http://localhost:6000/api
+PRIVATE_INTERNAL_API_HOST=http://localhost:5000/api
diff --git a/rate/handler.go b/rate/handler.go
index 311b5b8..7ab0b59 100644
--- a/rate/handler.go
+++ b/rate/handler.go
@@ -38,7 +38,7 @@ func (hn *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
// all public api endpoints are prefixed with this
- if !strings.HasPrefix(r.URL.Path, "/api/v2") && !strings.HasPrefix(r.URL.Path, "/api/v1") {
+ if !strings.HasPrefix(r.URL.Path, "/api/v2") {
w.WriteHeader(http.StatusNotFound)
return
}
diff --git a/rate/proxy-config.example.json b/rate/proxy-config.example.json
index 1ec9e59..427acef 100644
--- a/rate/proxy-config.example.json
+++ b/rate/proxy-config.example.json
@@ -1,6 +1,6 @@
{
"port": 5003,
- "proxy_target": "http://localhost:6000",
+ "proxy_target": "http://localhost:5000",
"debug": true,
"powered_by": "5 gay rats"
}