using Foxchat.Chat.Database; using Foxchat.Chat.Database.Models; using Foxchat.Chat.Middleware; using Foxchat.Core.Extensions; using Foxchat.Core.Federation; using Foxchat.Core.Models.Http; using Microsoft.AspNetCore.Mvc; using ApiError = Foxchat.Core.ApiError; namespace Foxchat.Chat.Controllers; [ApiController] [ServerUnauthenticated] [Route("/_fox/chat/hello")] public class HelloController( ILogger logger, ChatContext db, InstanceConfig config, RequestSigningService requestSigningService) : ControllerBase { [HttpPost] public async Task Hello([FromBody] Hello.HelloRequest req) { var node = await requestSigningService.RequestAsync(HttpMethod.Get, req.Host, "/_fox/ident/node"); if (!HttpContext.ExtractRequestData(out var signature, out var domain, out var signatureData)) throw new ApiError.IncomingFederationError("This endpoint requires signed requests."); if (domain != req.Host) throw new ApiError.IncomingFederationError("Host is invalid."); if (!requestSigningService.VerifySignature(node.PublicKey, signature, signatureData)) throw new ApiError.IncomingFederationError("Signature is not valid."); var instance = await db.GetInstanceAsync(); db.IdentityInstances.Add(new IdentityInstance { Domain = req.Host, BaseUrl = $"https://{req.Host}", PublicKey = node.PublicKey }); await db.SaveChangesAsync(); return Ok(new Hello.HelloResponse(instance.PublicKey, config.Domain)); } }