From 15e38a9bafde76247aa5e8fa0a0d0f8b8b71711b Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Tue, 11 Mar 2025 21:51:14 +0800 Subject: [PATCH] :sparkles: Support webfinger --- pkg/internal/http/api/index.go | 1 + pkg/internal/http/api/webfinger_api.go | 59 ++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 pkg/internal/http/api/webfinger_api.go diff --git a/pkg/internal/http/api/index.go b/pkg/internal/http/api/index.go index 3f347ab..bca4e90 100644 --- a/pkg/internal/http/api/index.go +++ b/pkg/internal/http/api/index.go @@ -7,6 +7,7 @@ import ( func MapAPIs(app *fiber.App, baseURL string) { api := app.Group(baseURL).Name("API") { + api.Get("/webfinger", getWebfinger) activitypub := api.Group("/activitypub").Name("ActivityPub API") { activitypub.Post("/users/:name/inbox", apUserInbox) diff --git a/pkg/internal/http/api/webfinger_api.go b/pkg/internal/http/api/webfinger_api.go new file mode 100644 index 0000000..d72dbf8 --- /dev/null +++ b/pkg/internal/http/api/webfinger_api.go @@ -0,0 +1,59 @@ +package api + +import ( + "git.solsynth.dev/hypernet/interactive/pkg/internal/database" + "git.solsynth.dev/hypernet/interactive/pkg/internal/models" + "git.solsynth.dev/hypernet/interactive/pkg/internal/services" + "github.com/gofiber/fiber/v2" +) + +type WebFingerResponse struct { + Subject string `json:"subject"` + Aliases []string `json:"aliases"` + Links []struct { + Rel string `json:"rel"` + Type string `json:"type,omitempty"` + Href string `json:"href"` + } `json:"links"` +} + +// Although this webfinger is desgined for users +// But in this case we will provide publisher for them +func getWebfinger(c *fiber.Ctx) error { + resource := c.Query("resource") + + if len(resource) < 6 || resource[:5] != "acct:" { + return c.Status(400).JSON(fiber.Map{"error": "Invalid resource format"}) + } + + username := resource[5:] + if username == "" { + return c.Status(400).JSON(fiber.Map{"error": "Invalid username"}) + } + + var publisher models.Publisher + if err := database.C.Where("name = ?", username).First(&publisher).Error; err != nil { + return fiber.NewError(fiber.StatusNotFound, err.Error()) + } + + response := WebFingerResponse{ + Subject: "acct:" + username, + Aliases: []string{ + services.GetActivityID("/users/" + publisher.Name).String(), + }, + Links: []struct { + Rel string `json:"rel"` + Type string `json:"type,omitempty"` + Href string `json:"href"` + }{ + { + Rel: "self", + Type: "application/activity+json", + Href: services.GetActivityID("/users/" + publisher.Name).String(), + }, + // TODO Add avatar here + }, + } + + return c.JSON(response) +}