Foxchat.NET/Foxchat.Chat/Controllers/HelloController.cs

47 lines
No EOL
1.6 KiB
C#

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<IActionResult> Hello([FromBody] Hello.HelloRequest req)
{
var node = await requestSigningService.RequestAsync<Hello.NodeInfo>(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));
}
}