2026-10-01 11:32:33 +02:00
|
|
|
using MongoDB.Entities;
|
|
|
|
|
|
2026-10-01 18:53:28 +02:00
|
|
|
using PrivaPub.Domain.Statuses;
|
2026-10-01 11:32:33 +02:00
|
|
|
using PrivaPub.Federation.Actors;
|
|
|
|
|
using PrivaPub.Models.Social;
|
|
|
|
|
using PrivaPub.Models.User;
|
|
|
|
|
using PrivaPub.StaticServices;
|
|
|
|
|
|
|
|
|
|
using System.Text.Json.Nodes;
|
|
|
|
|
|
|
|
|
|
using static PrivaPub.Federation.Objects.ActivityJson;
|
|
|
|
|
|
|
|
|
|
namespace PrivaPub.Federation.Inbox.Handlers
|
|
|
|
|
{
|
|
|
|
|
public class AcceptHandler : IActivityHandler
|
|
|
|
|
{
|
|
|
|
|
readonly DbEntities _dbEntities;
|
|
|
|
|
readonly ILocalActorService _localActors;
|
2026-10-01 18:53:28 +02:00
|
|
|
readonly IQuoteService _quotes;
|
2026-10-01 11:32:33 +02:00
|
|
|
|
2026-10-01 18:53:28 +02:00
|
|
|
public AcceptHandler(DbEntities dbEntities, ILocalActorService localActors, IQuoteService quotes)
|
2026-10-01 11:32:33 +02:00
|
|
|
{
|
|
|
|
|
_dbEntities = dbEntities;
|
|
|
|
|
_localActors = localActors;
|
2026-10-01 18:53:28 +02:00
|
|
|
_quotes = quotes;
|
2026-10-01 11:32:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual string Type => "Accept";
|
|
|
|
|
|
|
|
|
|
public async Task Handle(JsonNode activity, ForeignAvatar actor, CancellationToken token)
|
|
|
|
|
{
|
2026-10-01 18:53:28 +02:00
|
|
|
if (await _quotes.Answered(activity, actor, accepted: Type == "Accept", token))
|
|
|
|
|
return;
|
2026-10-01 11:32:33 +02:00
|
|
|
var following = await FindFollowing(activity["object"], actor, _dbEntities, _localActors, token);
|
|
|
|
|
if (following == default)
|
|
|
|
|
return;
|
|
|
|
|
await Apply(following, token);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual Task Apply(Following following, CancellationToken token) =>
|
|
|
|
|
DB.Default.Update<Following>().MatchID(following.ID).Modify(f => f.State, FollowState.Accepted).ExecuteAsync(token);
|
|
|
|
|
|
|
|
|
|
public static async Task<Following> FindFollowing(JsonNode follow, ForeignAvatar target, DbEntities dbEntities, ILocalActorService localActors,
|
|
|
|
|
CancellationToken token)
|
|
|
|
|
{
|
|
|
|
|
if (follow is JsonObject && Value(follow, "type") is { } type && type != "Follow")
|
|
|
|
|
return default;
|
|
|
|
|
var followId = Id(follow);
|
|
|
|
|
var byId = followId == default
|
|
|
|
|
? default
|
|
|
|
|
: await dbEntities.Followings.Match(f => f.FollowActivityURI == followId && f.TargetActorURI == target.ActorURI).ExecuteFirstAsync(token);
|
|
|
|
|
if (byId != default || follow is not JsonObject)
|
|
|
|
|
return byId;
|
|
|
|
|
|
|
|
|
|
var follower = await localActors.FindByUri(Id(follow["actor"]), token);
|
|
|
|
|
return follower == default
|
|
|
|
|
? default
|
|
|
|
|
: await dbEntities.Followings.Match(f => f.AvatarId == follower.Id && f.TargetActorURI == target.ActorURI).ExecuteFirstAsync(token);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class RejectHandler : AcceptHandler
|
|
|
|
|
{
|
2026-10-01 18:53:28 +02:00
|
|
|
public RejectHandler(DbEntities dbEntities, ILocalActorService localActors, IQuoteService quotes) : base(dbEntities, localActors, quotes)
|
2026-10-01 11:32:33 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string Type => "Reject";
|
|
|
|
|
|
|
|
|
|
protected override Task Apply(Following following, CancellationToken token) => DB.Default.DeleteAsync<Following>(following.ID);
|
|
|
|
|
}
|
|
|
|
|
}
|