diff --git a/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityHandlerService.cs b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityHandlerService.cs index c69d4403..57f37af8 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityHandlerService.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityHandlerService.cs @@ -85,6 +85,12 @@ public class ActivityHandlerService( return; } + if (activity.Object is ASNote note) + { + await noteSvc.DeleteNoteAsync(note, resolvedActor); + return; + } + if (activity.Object is not ASTombstone tombstone) throw GracefulException .UnprocessableEntity($"Delete activity object is invalid: {activity.Object?.Type}"); diff --git a/Iceshrimp.Backend/Core/Services/NoteService.cs b/Iceshrimp.Backend/Core/Services/NoteService.cs index 3ec6fa3c..fafdc9e5 100644 --- a/Iceshrimp.Backend/Core/Services/NoteService.cs +++ b/Iceshrimp.Backend/Core/Services/NoteService.cs @@ -569,6 +569,28 @@ public class NoteService( await DeleteNoteAsync(dbNote); } + + public async Task DeleteNoteAsync(ASNote note, User actor) + { + // ReSharper disable once EntityFramework.NPlusOne.IncompleteDataQuery (it doesn't know about IncludeCommonProperties()) + var dbNote = await db.Notes.IncludeCommonProperties().FirstOrDefaultAsync(p => p.Uri == note.Id); + if (dbNote == null) + { + logger.LogDebug("Note '{id}' isn't known, skipping", note.Id); + return; + } + + // ReSharper disable once EntityFramework.NPlusOne.IncompleteDataUsage (same reason as above) + if (dbNote.User != actor) + { + logger.LogDebug("Note '{id}' isn't owned by actor requesting its deletion, skipping", note.Id); + return; + } + + logger.LogDebug("Deleting note '{id}' owned by {userId}", note.Id, actor.Id); + + await DeleteNoteAsync(dbNote); + } public async Task UndoAnnounceAsync(ASNote note, User actor) {