diff --git a/Foxnouns.Backend/Controllers/Authentication/AuthController.cs b/Foxnouns.Backend/Controllers/Authentication/AuthController.cs index b9570c0..e8b3e76 100644 --- a/Foxnouns.Backend/Controllers/Authentication/AuthController.cs +++ b/Foxnouns.Backend/Controllers/Authentication/AuthController.cs @@ -1,14 +1,18 @@ using System.Web; +using Foxnouns.Backend.Database; using Foxnouns.Backend.Extensions; +using Foxnouns.Backend.Middleware; using Foxnouns.Backend.Services; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; using NodaTime; namespace Foxnouns.Backend.Controllers.Authentication; -[Route("/api/v2/auth")] -public class AuthController(Config config, KeyCacheService keyCache, ILogger logger) : ApiControllerBase +[Route("/api/internal/auth")] +public class AuthController(Config config, DatabaseContext db, KeyCacheService keyCache, ILogger logger) + : ApiControllerBase { private readonly ILogger _logger = logger.ForContext(); @@ -61,4 +65,15 @@ public class AuthController(Config config, KeyCacheService keyCache, ILogger log public record OauthRegisterRequest(string Ticket, string Username); public record CallbackRequest(string Code, string State); + + [HttpPost("force-log-out")] + [Authorize("identify")] + public async Task ForceLogoutAsync() + { + _logger.Information("Invalidating all tokens for user {UserId}", CurrentUser!.Id); + await db.Tokens.Where(t => t.UserId == CurrentUser.Id) + .ExecuteUpdateAsync(s => s.SetProperty(t => t.ManuallyExpired, true)); + + return NoContent(); + } } \ No newline at end of file diff --git a/Foxnouns.Backend/Controllers/Authentication/DiscordAuthController.cs b/Foxnouns.Backend/Controllers/Authentication/DiscordAuthController.cs index a1c3eed..f08569a 100644 --- a/Foxnouns.Backend/Controllers/Authentication/DiscordAuthController.cs +++ b/Foxnouns.Backend/Controllers/Authentication/DiscordAuthController.cs @@ -10,7 +10,7 @@ using NodaTime; namespace Foxnouns.Backend.Controllers.Authentication; -[Route("/api/v2/auth/discord")] +[Route("/api/internal/auth/discord")] public class DiscordAuthController( [UsedImplicitly] Config config, ILogger logger, diff --git a/Foxnouns.Backend/Controllers/Authentication/EmailAuthController.cs b/Foxnouns.Backend/Controllers/Authentication/EmailAuthController.cs index 18fbacc..251fb5f 100644 --- a/Foxnouns.Backend/Controllers/Authentication/EmailAuthController.cs +++ b/Foxnouns.Backend/Controllers/Authentication/EmailAuthController.cs @@ -1,6 +1,7 @@ using Foxnouns.Backend.Database; using Foxnouns.Backend.Database.Models; using Foxnouns.Backend.Extensions; +using Foxnouns.Backend.Middleware; using Foxnouns.Backend.Services; using Foxnouns.Backend.Utils; using JetBrains.Annotations; @@ -10,7 +11,7 @@ using NodaTime; namespace Foxnouns.Backend.Controllers.Authentication; -[Route("/api/v2/auth/email")] +[Route("/api/internal/auth/email")] public class EmailAuthController( [UsedImplicitly] Config config, DatabaseContext db, @@ -123,6 +124,17 @@ public class EmailAuthController( )); } + [HttpPost("add")] + [Authorize("*")] + public async Task AddEmailAddressAsync() + { + _logger.Information("beep"); + + return NoContent(); + } + + public record AddEmailAddressRequest(string Email, string Password); + private void CheckRequirements() { if (!config.EmailAuth.Enabled) diff --git a/Foxnouns.Backend/Controllers/InternalController.cs b/Foxnouns.Backend/Controllers/InternalController.cs index 2048f59..b79de1c 100644 --- a/Foxnouns.Backend/Controllers/InternalController.cs +++ b/Foxnouns.Backend/Controllers/InternalController.cs @@ -1,35 +1,17 @@ using System.Text.RegularExpressions; using Foxnouns.Backend.Database; -using Foxnouns.Backend.Middleware; using Foxnouns.Backend.Utils; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Routing; using Microsoft.AspNetCore.Routing.Template; -using Microsoft.EntityFrameworkCore; namespace Foxnouns.Backend.Controllers; [ApiController] [Route("/api/internal")] -public partial class InternalController(ILogger logger, DatabaseContext db) : ControllerBase +public partial class InternalController(DatabaseContext db) : ControllerBase { - private readonly ILogger _logger = logger.ForContext(); - - [HttpPost("force-log-out")] - [Authenticate] - [Authorize("identify")] - public async Task ForceLogoutAsync() - { - var user = HttpContext.GetUser()!; - - _logger.Information("Invalidating all tokens for user {UserId}", user.Id); - await db.Tokens.Where(t => t.UserId == user.Id) - .ExecuteUpdateAsync(s => s.SetProperty(t => t.ManuallyExpired, true)); - - return NoContent(); - } - [GeneratedRegex(@"(\{\w+\})")] private static partial Regex PathVarRegex(); diff --git a/Foxnouns.Backend/Utils/AuthUtils.cs b/Foxnouns.Backend/Utils/AuthUtils.cs index c767198..c7bd717 100644 --- a/Foxnouns.Backend/Utils/AuthUtils.cs +++ b/Foxnouns.Backend/Utils/AuthUtils.cs @@ -27,7 +27,7 @@ public static class AuthUtils public static string[] ExpandScopes(this string[] scopes) { - if (scopes.Contains("*")) return Scopes; + if (scopes.Contains("*")) return ["*", ..Scopes]; List expandedScopes = ["identify"]; if (scopes.Contains("user")) expandedScopes.AddRange(UserScopes); if (scopes.Contains("member")) expandedScopes.AddRange(MemberScopes); diff --git a/Foxnouns.Frontend/app/lib/request.server.ts b/Foxnouns.Frontend/app/lib/request.server.ts index 7777422..c92f67d 100644 --- a/Foxnouns.Frontend/app/lib/request.server.ts +++ b/Foxnouns.Frontend/app/lib/request.server.ts @@ -16,7 +16,7 @@ async function requestInternal( path: string, params: RequestParams = {}, ): Promise { - const base = params.isInternal ? INTERNAL_API_BASE : API_BASE + "/v2"; + const base = params.isInternal ? INTERNAL_API_BASE + "/internal" : API_BASE + "/v2"; const url = `${base}${path}`; const resp = await fetch(url, { diff --git a/Foxnouns.Frontend/app/routes/auth.callback.discord/route.tsx b/Foxnouns.Frontend/app/routes/auth.callback.discord/route.tsx index c5200fd..5fb246c 100644 --- a/Foxnouns.Frontend/app/routes/auth.callback.discord/route.tsx +++ b/Foxnouns.Frontend/app/routes/auth.callback.discord/route.tsx @@ -43,6 +43,7 @@ export const loader = async ({ request }: LoaderFunctionArgs) => { const resp = await serverRequest("POST", "/auth/discord/callback", { body: { code, state }, + isInternal: true, }); if (resp.has_account) { @@ -89,6 +90,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { try { const resp = await serverRequest("POST", "/auth/discord/register", { body: { username, ticket }, + isInternal: true, }); return redirect("/auth/welcome", { diff --git a/Foxnouns.Frontend/app/routes/auth.log-in/route.tsx b/Foxnouns.Frontend/app/routes/auth.log-in/route.tsx index fc25d75..eadbaa9 100644 --- a/Foxnouns.Frontend/app/routes/auth.log-in/route.tsx +++ b/Foxnouns.Frontend/app/routes/auth.log-in/route.tsx @@ -41,7 +41,7 @@ export const loader = async ({ request }: LoaderFunctionArgs) => { } } - const urls = await serverRequest("POST", "/auth/urls"); + const urls = await serverRequest("POST", "/auth/urls", { isInternal: true }); return json({ meta: { title: t("log-in.title") }, @@ -57,6 +57,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { try { const resp = await serverRequest("POST", "/auth/email/login", { body: { email, password }, + isInternal: true, }); return redirect("/", { diff --git a/Foxnouns.Frontend/app/routes/settings.force-log-out/route.tsx b/Foxnouns.Frontend/app/routes/settings.force-log-out/route.tsx index caa9d4a..608761b 100644 --- a/Foxnouns.Frontend/app/routes/settings.force-log-out/route.tsx +++ b/Foxnouns.Frontend/app/routes/settings.force-log-out/route.tsx @@ -10,7 +10,7 @@ export const action: ActionFunction = async ({ request }) => { headers: { "Set-Cookie": writeCookie(tokenCookieName, "token", 0) }, }); - await fastRequest("POST", "/internal/force-log-out", { token, isInternal: true }); + await fastRequest("POST", "/auth/force-log-out", { token, isInternal: true }); return redirect("/", { status: 303,