diff --git a/routers/init.go b/routers/init.go index 90a1cb1e89..9a304527fa 100644 --- a/routers/init.go +++ b/routers/init.go @@ -38,6 +38,7 @@ import ( "forgejo.org/services/auth/source/oauth2" "forgejo.org/services/automerge" "forgejo.org/services/cron" + federation_service "forgejo.org/services/federation" feed_service "forgejo.org/services/feed" indexer_service "forgejo.org/services/indexer" "forgejo.org/services/mailer" @@ -122,6 +123,7 @@ func InitWebInstalled(ctx context.Context) { mailer.NewContext(ctx) mustInit(cache.Init) mustInit(feed_service.Init) + mustInit(federation_service.Init) mustInit(uinotification.Init) mustInitCtx(ctx, archiver.Init) diff --git a/routers/web/webfinger.go b/routers/web/webfinger.go index be3c2925fe..372c08f7d8 100644 --- a/routers/web/webfinger.go +++ b/routers/web/webfinger.go @@ -58,7 +58,33 @@ func WebfingerQuery(ctx *context.Context) { return } + // Instance actor + if parts[0] == "ghost" { + aliases := []string{ + appURL.String() + "api/v1/activitypub/actor", + } + + links := []*webfingerLink{ + { + Rel: "self", + Type: "application/activity+json", + Href: appURL.String() + "api/v1/activitypub/actor", + }, + } + + ctx.Resp.Header().Add("Access-Control-Allow-Origin", "*") + ctx.JSON(http.StatusOK, &webfingerJRD{ + Subject: fmt.Sprintf("acct:%s@%s", "ghost", appURL.Host), + Aliases: aliases, + Links: links, + }) + ctx.Resp.Header().Set("Content-Type", "application/jrd+json") + + return + } + u, err = user_model.GetUserByName(ctx, parts[0]) + case "mailto": u, err = user_model.GetUserByEmail(ctx, resource.Opaque) if u != nil && u.KeepEmailPrivate { diff --git a/tests/integration/webfinger_test.go b/tests/integration/webfinger_test.go index 078be6fa54..9708fc1627 100644 --- a/tests/integration/webfinger_test.go +++ b/tests/integration/webfinger_test.go @@ -52,6 +52,15 @@ func TestWebfinger(t *testing.T) { assert.Equal(t, "acct:user2@"+appURL.Host, jrd.Subject) assert.ElementsMatch(t, []string{user.HTMLURL(), appURL.String() + "api/v1/activitypub/user-id/" + fmt.Sprint(user.ID)}, jrd.Aliases) + instanceReq := NewRequest(t, "GET", fmt.Sprintf("/.well-known/webfinger?resource=acct:ghost@%s", appURL.Host)) + instanceResp := MakeRequest(t, instanceReq, http.StatusOK) + assert.Equal(t, "application/jrd+json", instanceResp.Header().Get("Content-Type")) + + var instanceActor webfingerJRD + DecodeJSON(t, instanceResp, &instanceActor) + assert.Equal(t, "acct:ghost@"+appURL.Host, instanceActor.Subject) + assert.ElementsMatch(t, []string{appURL.String() + "api/v1/activitypub/actor"}, instanceActor.Aliases) + req = NewRequest(t, "GET", fmt.Sprintf("/.well-known/webfinger?resource=acct:%s@%s", user.LowerName, "unknown.host")) MakeRequest(t, req, http.StatusBadRequest)