using MongoDB.Entities; using PrivaPub.Federation.Actors; using PrivaPub.Federation.Objects; using PrivaPub.Federation.Outbox; using PrivaPub.Federation.Rendering; using PrivaPub.Models.Federation; using PrivaPub.Models.Group; using PrivaPub.Models.Post; using PrivaPub.Models.User; using PrivaPub.StaticServices; using System.Text.Json.Nodes; using static PrivaPub.Federation.Inbox.ForeignMembers; using static PrivaPub.Federation.Objects.ActivityJson; using PostEntity = PrivaPub.Models.Post.Post; namespace PrivaPub.Federation.Inbox.Handlers { public class UndoHandler : IActivityHandler { readonly DbEntities _dbEntities; readonly ILocalActorService _localActors; readonly IRemoteActorService _remoteActors; readonly IDeliveryService _delivery; public UndoHandler(DbEntities dbEntities, ILocalActorService localActors, IRemoteActorService remoteActors, IDeliveryService delivery) { _dbEntities = dbEntities; _localActors = localActors; _remoteActors = remoteActors; _delivery = delivery; } public string Type => "Undo"; public async Task Handle(JsonNode activity, ForeignAvatar actor, CancellationToken token) { var undo = activity; var inner = undo["object"]; var innerType = inner is JsonObject ? Value(inner, "type") : default; var innerId = Id(inner); if (inner is JsonObject && Id(inner["actor"]) != actor.ActorURI) return; if (innerType is not (null or "Follow")) return; var followers = await _dbEntities.Followers.Match(f => f.ActorURI == actor.ActorURI).ExecuteAsync(token); var targetUri = inner is JsonObject ? Id(inner["object"]) : default; foreach (var follower in followers) { var matchesActivity = innerId != default && follower.FollowActivityURI == innerId; var target = targetUri == default ? default : await _localActors.FindByUri(targetUri, token); var matchesTarget = target != default && target.Id == follower.LocalActorId && target.Kind == follower.LocalActorKind; if (!matchesActivity && !matchesTarget) continue; await DB.Default.DeleteAsync(follower.ID); if (follower.LocalActorKind == LocalActorKind.Group) await RemoveForeignMember(follower.LocalActorId, actor.ActorURI, token); } return; } } }