fix: harden ActivityPub federation and fix N+1 follower fanout (#1056)

* initial commit

* improve activitypub recipient query

* small fixes

---------

Co-authored-by: Christian Beutel <>
Co-authored-by: slothful-vassal <89943360+slothful-vassal@users.noreply.github.com>
This commit is contained in:
Flomp
2026-06-18 16:36:57 +02:00
committed by GitHub
parent 6baeafe755
commit 64da36aa20
6 changed files with 86 additions and 92 deletions

View File

@@ -12,7 +12,6 @@ import (
"pocketbase/util"
pub "github.com/go-ap/activitypub"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tools/filesystem"
"github.com/pocketbase/pocketbase/tools/security"
@@ -89,19 +88,11 @@ func CreateTrailActivity(app core.App, ctx context.Context, trail *core.Record,
return err
}
follows, err := app.FindRecordsByFilter("follows", "followee={:followee}&&status='accepted'", "", -1, 0, dbx.Params{"followee": trailAuthor.Id})
inboxes, err := followerInboxes(app, trailAuthor.Id)
if err != nil {
return err
}
recipients := mentions
for _, f := range follows {
follower, err := app.FindRecordById("activitypub_actors", f.GetString("follower"))
if err != nil {
return err
}
recipients = append(recipients, follower.GetString("inbox"))
}
recipients := append(mentions, inboxes...)
return PostActivity(app, trailAuthor, activity, recipients)
}
@@ -264,15 +255,14 @@ func CreateSummitLogActivity(app core.App, ctx context.Context, summitLog *core.
gpx = fmt.Sprintf("%s/api/v1/files/summit_logs/%s/%s", origin, summitLog.Id, summitLog.GetString("gpx"))
}
attachments := make(pub.ItemCollection, max(len(photos), 2))
attachments := make(pub.ItemCollection, 0, len(photos)+1)
for i := range len(photos) {
iri := fmt.Sprintf("%s/api/v1/files/summit_logs/%s/%s", origin, summitLog.Id, photos[i])
attachments[i] = pub.Document{
attachments.Append(pub.Document{
Type: pub.ImageType,
MediaType: "image/jpeg",
URL: pub.IRI(iri),
}
})
}
if gpx != "" {
attachments.Append(pub.Document{
@@ -328,20 +318,11 @@ func CreateSummitLogActivity(app core.App, ctx context.Context, summitLog *core.
activity.CC = cc
activity.Published = time.Now()
follows, err := app.FindRecordsByFilter("follows", "followee={:followee}&&status='accepted'", "", -1, 0, dbx.Params{"followee": summitLogAuthor.Id})
inboxes, err := followerInboxes(app, summitLogAuthor.Id)
if err != nil {
return err
}
recipients := mentions
for _, f := range follows {
follower, err := app.FindRecordById("activitypub_actors", f.GetString("follower"))
if err != nil {
return err
}
recipients = append(recipients, follower.GetString("inbox"))
}
recipients := append(mentions, inboxes...)
if summitLogAuthor.Id != summitLogTrailAuthor.Id {
recipients = append(recipients, summitLogTrailAuthor.GetString("inbox"))
@@ -405,20 +386,11 @@ func CreateListActivity(app core.App, list *core.Record, typ pub.ActivityVocabul
return err
}
follows, err := app.FindRecordsByFilter("follows", "followee={:followee}&&status='accepted'", "", -1, 0, dbx.Params{"followee": listAuthor.Id})
recipients, err := followerInboxes(app, listAuthor.Id)
if err != nil {
return err
}
recipients := []string{}
for _, f := range follows {
follower, err := app.FindRecordById("activitypub_actors", f.GetString("follower"))
if err != nil {
return err
}
recipients = append(recipients, follower.GetString("inbox"))
}
err = PostActivity(app, listAuthor, activity, recipients)
if err != nil {
return err
@@ -469,7 +441,10 @@ func processCreateOrUpdateTrailActivity(activity pub.Activity, app core.App, act
return err
}
trailObject, _ := pub.ToObject(activity.Object)
trailObject, err := pub.ToObject(activity.Object)
if err != nil {
return err
}
for _, t := range trailObject.Tag {
if t.GetType() == pub.MentionType {
@@ -487,11 +462,11 @@ func processCreateOrUpdateTrailActivity(activity pub.Activity, app core.App, act
Seen: false,
Author: actor.Id,
}
return util.SendNotification(app, notification, mentionedActor)
util.SendNotification(app, notification, mentionedActor)
}
}
return err
return nil
}
func processCreateOrUpdateCommentActivity(activity pub.Activity, app core.App, actor *core.Record) error {
@@ -578,7 +553,7 @@ func processCreateOrUpdateCommentActivity(activity pub.Activity, app core.App, a
Seen: false,
Author: actor.Id,
}
return util.SendNotification(app, notification, mentionedActor)
util.SendNotification(app, notification, mentionedActor)
}
}
if activity.Type == pub.CreateType {
@@ -629,6 +604,11 @@ func processCreateOrUpdateSummitLogActivity(activity pub.Activity, app core.App,
return err
}
// no need to do anything else if the actor is local
if actor.GetBool("is_local") {
return nil
}
newSummitLog := false
record, err := app.FindFirstRecordByData("summit_logs", "iri", logObject.ID.String())
if err != nil {
@@ -644,10 +624,6 @@ func processCreateOrUpdateSummitLogActivity(activity pub.Activity, app core.App,
return err
}
}
// no need to do anything else if the actor is local
if actor.GetBool("is_local") {
return nil
}
var distance, duration, elevation_gain, elevation_loss float64
tags, err := pub.ToItemCollection(logObject.Tag)
@@ -752,7 +728,7 @@ func processCreateOrUpdateSummitLogActivity(activity pub.Activity, app core.App,
Seen: false,
Author: actor.Id,
}
return util.SendNotification(app, notification, mentionedActor)
util.SendNotification(app, notification, mentionedActor)
}
}