2024-05-21 17:45:35 +02:00
|
|
|
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]
|
2024-05-21 20:14:52 +02:00
|
|
|
[ServerUnauthenticated]
|
2024-05-21 17:45:35 +02:00
|
|
|
[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.");
|
2024-05-21 20:14:52 +02:00
|
|
|
if (domain != req.Host)
|
|
|
|
throw new ApiError.IncomingFederationError("Host is invalid.");
|
2024-05-21 17:45:35 +02:00
|
|
|
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
}
|