using Foxchat.Core; using Foxchat.Core.Federation; using Foxchat.Identity.Middleware; using Foxchat.Identity.Services; using Microsoft.AspNetCore.Mvc; namespace Foxchat.Identity.Controllers.Proxy; [ApiController] [ClientAuthenticate] public class ProxyControllerBase( ILogger logger, ChatInstanceResolverService chatInstanceResolverService, RequestSigningService requestSigningService) : ControllerBase { internal async Task Proxy(HttpMethod method, object? body = null) where TResponse : class { var acct = HttpContext.GetAccountOrThrow(); var path = HttpContext.Request.Path.ToString(); if (!path.StartsWith("/_fox/proxy")) throw new FoxchatError("Proxy used for endpoint that does not start with /_fox/proxy"); path = $"/_fox/chat/{path[12..]}"; if (!HttpContext.Request.Headers.TryGetValue(RequestSigningService.SERVER_HEADER, out var serverHeader)) throw new ApiError.BadRequest($"Invalid or missing {RequestSigningService.SERVER_HEADER} header."); var server = serverHeader.ToString(); logger.Debug("Proxying {Method} request to {Domain}{Path}", method, server, path); // Identity instances always initiate federation, so we have to make sure the instance knows about us. // This also serves as a way to make sure the instance being requested actually exists. await chatInstanceResolverService.ResolveChatInstanceAsync(serverHeader.ToString()); var resp = await requestSigningService.RequestAsync(method, server, path, acct.Id.ToString(), body); return Ok(resp); } }