From 9e23f82e55382332adc775f8a21c6f1af47e1034 Mon Sep 17 00:00:00 2001 From: mstar Date: Thu, 12 Jun 2025 17:13:19 +0200 Subject: [PATCH] And follow requests work! Who knew that Mastodon would set the accept target's object id to the internal one? But also, I am of the opinion that this is a bug on our side when translating the activity to AP --- web/public/api/activitypub/inbox.go | 50 +++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/web/public/api/activitypub/inbox.go b/web/public/api/activitypub/inbox.go index 474b597..a0fde7b 100644 --- a/web/public/api/activitypub/inbox.go +++ b/web/public/api/activitypub/inbox.go @@ -387,6 +387,7 @@ func handleAccept(w http.ResponseWriter, r *http.Request, object map[string]any) log := hlog.FromRequest(r) rawTarget, ok := object["object"] if !ok { + log.Debug().Msg("Rejecting accept, missing object") _ = webutils.ProblemDetails( w, http.StatusBadRequest, @@ -397,7 +398,6 @@ func handleAccept(w http.ResponseWriter, r *http.Request, object map[string]any) ) return true } - // FIXME: Also handle other undo cases, such as follows var targetObjectId string // I *think* the spec says that this must be an object. Not sure though switch target := rawTarget.(type) { @@ -406,7 +406,20 @@ func handleAccept(w http.ResponseWriter, r *http.Request, object map[string]any) case map[string]any: objType, ok := target["type"].(string) // TODO: Ensure accept is only used for follows - if !ok || objType != "Follow" { + if !ok { + log.Debug().Msg("Rejecting accept, missing embedded object data") + _ = webutils.ProblemDetails( + w, + http.StatusBadRequest, + "/errors/bad-request-data", + "Bad activity data", + other.IntoPointer(`Target object must contain a type field`), + nil, + ) + return true + } + if objType != "Follow" { + log.Debug().Msg("Rejecting accept, bad object type") _ = webutils.ProblemDetails( w, http.StatusBadRequest, @@ -419,6 +432,7 @@ func handleAccept(w http.ResponseWriter, r *http.Request, object map[string]any) } targetObjectId, ok = target["id"].(string) if !ok { + log.Debug().Msg("Rejecting accept, missing object id") _ = webutils.ProblemDetails( w, http.StatusBadRequest, @@ -430,6 +444,7 @@ func handleAccept(w http.ResponseWriter, r *http.Request, object map[string]any) return true } default: + log.Debug().Msg("Rejecting accept, missing object field") _ = webutils.ProblemDetails( w, http.StatusBadRequest, @@ -440,22 +455,29 @@ func handleAccept(w http.ResponseWriter, r *http.Request, object map[string]any) ) return true } - internalIdMatch := objectIdRegex.FindStringSubmatch(targetObjectId) - if len(internalIdMatch) != 2 { - _ = webutils.ProblemDetails( - w, - http.StatusBadRequest, - "/errors/bad-request-data", - "Bad activity data", - other.IntoPointer(`Request data target object is not internal id`), - nil, - ) - return true + var internalId string + if strings.HasPrefix(targetObjectId, "http") { + internalIdMatch := objectIdRegex.FindStringSubmatch(targetObjectId) + if len(internalIdMatch) != 2 { + log.Debug().Msg("Rejecting accept, objectIdRegex didn't match") + _ = webutils.ProblemDetails( + w, + http.StatusBadRequest, + "/errors/bad-request-data", + "Bad activity data", + other.IntoPointer(`Request data target object is not internal id`), + nil, + ) + return true + } + internalId = internalIdMatch[1] + } else { + internalId = targetObjectId } - internalId := internalIdMatch[1] followActivity, err := dbgen.Activity.Where(dbgen.Activity.Id.Eq(internalId)).First() switch err { case gorm.ErrRecordNotFound: + log.Debug().Msg("Rejecting accept, target follow activity not found") _ = webutils.ProblemDetailsStatusOnly(w, http.StatusNotFound) return true case nil: