Compare commits
No commits in common. "478ba2a4065f1aa18e2dc5c5f8f9db761ece6e16" and "7791c9196091d9c6bbeb2fda46f0913b925cc4b7" have entirely different histories.
478ba2a406
...
7791c91960
15 changed files with 38 additions and 458 deletions
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
using Foxnouns.Backend.Database;
|
using Foxnouns.Backend.Database;
|
||||||
using Foxnouns.Backend.Middleware;
|
using Foxnouns.Backend.Middleware;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
|
@ -38,8 +38,6 @@ public partial class InternalController(DatabaseContext db) : ControllerBase
|
||||||
{
|
{
|
||||||
if (template.StartsWith("api/v2"))
|
if (template.StartsWith("api/v2"))
|
||||||
template = template["api/v2".Length..];
|
template = template["api/v2".Length..];
|
||||||
else if (template.StartsWith("api/v1"))
|
|
||||||
template = template["api/v1".Length..];
|
|
||||||
template = PathVarRegex()
|
template = PathVarRegex()
|
||||||
.Replace(template, "{id}") // Replace all path variables (almost always IDs) with `{id}`
|
.Replace(template, "{id}") // Replace all path variables (almost always IDs) with `{id}`
|
||||||
.Replace("@me", "{id}"); // Also replace hardcoded `@me` with `{id}`
|
.Replace("@me", "{id}"); // Also replace hardcoded `@me` with `{id}`
|
||||||
|
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
using Foxnouns.Backend.Database;
|
using Foxnouns.Backend.Database;
|
||||||
using Foxnouns.Backend.Database.Models;
|
using Foxnouns.Backend.Database.Models;
|
||||||
using Foxnouns.Backend.Middleware;
|
using Foxnouns.Backend.Middleware;
|
||||||
|
|
16
Foxnouns.Backend/Controllers/V1/UsersV1Controller.cs
Normal file
16
Foxnouns.Backend/Controllers/V1/UsersV1Controller.cs
Normal file
|
@ -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<IActionResult> GetUserAsync(string userRef, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
User user = await usersV1Service.ResolveUserAsync(userRef, CurrentToken, ct);
|
||||||
|
return Ok(await usersV1Service.RenderUserAsync(user));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
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<IActionResult> 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<IActionResult> 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<IActionResult> GetUserMembersAsync(
|
|
||||||
string userRef,
|
|
||||||
CancellationToken ct = default
|
|
||||||
)
|
|
||||||
{
|
|
||||||
User user = await usersV1Service.ResolveUserAsync(userRef, CurrentToken, ct);
|
|
||||||
List<Member> members = await db
|
|
||||||
.Members.Where(m => m.UserId == user.Id)
|
|
||||||
.OrderBy(m => m.Name)
|
|
||||||
.ToListAsync(ct);
|
|
||||||
|
|
||||||
List<MemberResponse> 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<IActionResult> 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
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// 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<Guid, CustomPreference> CustomPreferences
|
|
||||||
);
|
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// ReSharper disable NotAccessedPositionalProperty.Global
|
// ReSharper disable NotAccessedPositionalProperty.Global
|
||||||
using Foxnouns.Backend.Database;
|
using Foxnouns.Backend.Database;
|
||||||
using Foxnouns.Backend.Database.Models;
|
using Foxnouns.Backend.Database.Models;
|
||||||
|
@ -36,8 +21,6 @@ public record UserResponse(
|
||||||
FieldEntry[] Names,
|
FieldEntry[] Names,
|
||||||
PronounEntry[] Pronouns,
|
PronounEntry[] Pronouns,
|
||||||
ProfileField[] Fields,
|
ProfileField[] Fields,
|
||||||
PrideFlag[] Flags,
|
|
||||||
PartialMember[] Members,
|
|
||||||
int? UtcOffset,
|
int? UtcOffset,
|
||||||
Dictionary<Guid, CustomPreference> CustomPreferences
|
Dictionary<Guid, CustomPreference> CustomPreferences
|
||||||
);
|
);
|
||||||
|
@ -92,5 +75,3 @@ public record PronounEntry(string Pronouns, string? DisplayText, string Status)
|
||||||
))
|
))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public record PrideFlag(string Id, Snowflake IdNew, string Hash, string Name, string? Description);
|
|
||||||
|
|
|
@ -130,8 +130,7 @@ public static class WebApplicationExtensions
|
||||||
.AddTransient<CreateFlagInvocable>()
|
.AddTransient<CreateFlagInvocable>()
|
||||||
.AddTransient<CreateDataExportInvocable>()
|
.AddTransient<CreateDataExportInvocable>()
|
||||||
// Legacy services
|
// Legacy services
|
||||||
.AddScoped<UsersV1Service>()
|
.AddScoped<UsersV1Service>();
|
||||||
.AddScoped<MembersV1Service>();
|
|
||||||
|
|
||||||
if (!config.Logging.EnableMetrics)
|
if (!config.Logging.EnableMetrics)
|
||||||
services.AddHostedService<BackgroundMetricsCollectionService>();
|
services.AddHostedService<BackgroundMetricsCollectionService>();
|
||||||
|
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
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<Member> 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<Member> 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<MemberResponse> 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<MemberFlag> 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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
using Foxnouns.Backend.Database;
|
using Foxnouns.Backend.Database;
|
||||||
using Foxnouns.Backend.Database.Models;
|
using Foxnouns.Backend.Database.Models;
|
||||||
using Foxnouns.Backend.Dto.V1;
|
using Foxnouns.Backend.Dto.V1;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using FieldEntry = Foxnouns.Backend.Dto.V1.FieldEntry;
|
using FieldEntry = Foxnouns.Backend.Dto.V1.FieldEntry;
|
||||||
using PrideFlag = Foxnouns.Backend.Dto.V1.PrideFlag;
|
|
||||||
|
|
||||||
namespace Foxnouns.Backend.Services.V1;
|
namespace Foxnouns.Backend.Services.V1;
|
||||||
|
|
||||||
|
@ -64,26 +49,8 @@ public class UsersV1Service(DatabaseContext db)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<UserResponse> RenderUserAsync(
|
public async Task<UserResponse> RenderUserAsync(User user)
|
||||||
User user,
|
|
||||||
Token? token = null,
|
|
||||||
bool renderMembers = true,
|
|
||||||
bool renderFlags = true,
|
|
||||||
CancellationToken ct = default
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
bool isSelfUser = user.Id == token?.UserId;
|
|
||||||
renderMembers = renderMembers && (isSelfUser || !user.ListHidden);
|
|
||||||
|
|
||||||
// Only fetch members if we're rendering members (duh)
|
|
||||||
List<Member> members = renderMembers
|
|
||||||
? await db.Members.Where(m => m.UserId == user.Id).OrderBy(m => m.Name).ToListAsync(ct)
|
|
||||||
: [];
|
|
||||||
|
|
||||||
List<UserFlag> flags = renderFlags
|
|
||||||
? await db.UserFlags.Where(f => f.UserId == user.Id).OrderBy(f => f.Id).ToListAsync(ct)
|
|
||||||
: [];
|
|
||||||
|
|
||||||
int? utcOffset = null;
|
int? utcOffset = null;
|
||||||
if (
|
if (
|
||||||
user.Timezone != null
|
user.Timezone != null
|
||||||
|
@ -103,30 +70,11 @@ public class UsersV1Service(DatabaseContext db)
|
||||||
user.MemberTitle,
|
user.MemberTitle,
|
||||||
user.Avatar,
|
user.Avatar,
|
||||||
user.Links,
|
user.Links,
|
||||||
Names: FieldEntry.FromEntries(user.Names, user.CustomPreferences),
|
FieldEntry.FromEntries(user.Names, user.CustomPreferences),
|
||||||
Pronouns: PronounEntry.FromPronouns(user.Pronouns, user.CustomPreferences),
|
PronounEntry.FromPronouns(user.Pronouns, user.CustomPreferences),
|
||||||
Fields: ProfileField.FromFields(user.Fields, user.CustomPreferences),
|
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(),
|
|
||||||
utcOffset,
|
utcOffset,
|
||||||
CustomPreferences: RenderCustomPreferences(user.CustomPreferences)
|
user.CustomPreferences.Select(x =>
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Dictionary<Guid, CustomPreference> RenderCustomPreferences(
|
|
||||||
Dictionary<Snowflake, User.CustomPreference> customPreferences
|
|
||||||
) =>
|
|
||||||
customPreferences
|
|
||||||
.Select(x =>
|
|
||||||
(
|
(
|
||||||
x.Value.LegacyId,
|
x.Value.LegacyId,
|
||||||
new CustomPreference(
|
new CustomPreference(
|
||||||
|
@ -138,32 +86,7 @@ public class UsersV1Service(DatabaseContext db)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.ToDictionary();
|
.ToDictionary()
|
||||||
|
|
||||||
private static PartialMember RenderPartialMember(
|
|
||||||
Member m,
|
|
||||||
Dictionary<Snowflake, User.CustomPreference> 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)
|
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
using Foxnouns.Backend.Database;
|
using Foxnouns.Backend.Database;
|
||||||
using Foxnouns.Backend.Database.Models;
|
using Foxnouns.Backend.Database.Models;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
; The host the server will listen on
|
; The host the server will listen on
|
||||||
Host = localhost
|
Host = localhost
|
||||||
; The port the server will listen on
|
; The port the server will listen on
|
||||||
Port = 6000
|
Port = 5000
|
||||||
; The base *external* URL
|
; The base *external* URL
|
||||||
BaseUrl = https://pronouns.localhost
|
BaseUrl = https://pronouns.localhost
|
||||||
; The base URL for media, without a trailing slash. This must be publicly accessible.
|
; The base URL for media, without a trailing slash. This must be publicly accessible.
|
||||||
|
|
|
@ -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_LANGUAGE=en
|
||||||
PUBLIC_BASE_URL=https://pronouns.cc
|
PUBLIC_BASE_URL=https://pronouns.cc
|
||||||
PUBLIC_SHORT_URL=https://prns.cc
|
PUBLIC_SHORT_URL=https://prns.cc
|
||||||
PUBLIC_API_BASE=https://pronouns.cc/api
|
PUBLIC_API_BASE=https://pronouns.cc/api
|
||||||
PRIVATE_API_HOST=http://localhost:5003/api
|
PRIVATE_API_HOST=http://localhost:5003/api
|
||||||
PRIVATE_INTERNAL_API_HOST=http://localhost:6000/api
|
PRIVATE_INTERNAL_API_HOST=http://localhost:5000/api
|
||||||
|
|
|
@ -38,7 +38,7 @@ func (hn *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// all public api endpoints are prefixed with this
|
// 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)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"port": 5003,
|
"port": 5003,
|
||||||
"proxy_target": "http://localhost:6000",
|
"proxy_target": "http://localhost:5000",
|
||||||
"debug": true,
|
"debug": true,
|
||||||
"powered_by": "5 gay rats"
|
"powered_by": "5 gay rats"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue