From b922b8382084eeff3ee95a349eeb9cd0a610745c Mon Sep 17 00:00:00 2001 From: bnewbold Date: Sat, 23 Dec 2023 21:38:21 +0100 Subject: [PATCH] yet more RSS tweaks (#2289) * rss: full URL in RSS link; use request Host in URLs Full URL syntax on request from third parties. Using the actual request host should fix issues with non-bsky-production deployments. It is HTTPS-only, so doesn't work perfectly for local dev. * rss: make /profile/{handle}/rss an HTTP redirect Motivation is easier discoverability of RSS feed. --- bskyweb/cmd/bskyweb/rss.go | 33 ++++++++++++++++++++++++++++----- bskyweb/cmd/bskyweb/server.go | 3 ++- bskyweb/templates/profile.html | 4 +++- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/bskyweb/cmd/bskyweb/rss.go b/bskyweb/cmd/bskyweb/rss.go index 4cdc78f8..64e67fd2 100644 --- a/bskyweb/cmd/bskyweb/rss.go +++ b/bskyweb/cmd/bskyweb/rss.go @@ -4,6 +4,7 @@ import ( "encoding/xml" "fmt" "net/http" + "strings" "time" appbsky "github.com/bluesky-social/indigo/api/bsky" @@ -39,11 +40,33 @@ type rss struct { func (srv *Server) WebProfileRSS(c echo.Context) error { ctx := c.Request().Context() + req := c.Request() - didParam := c.Param("did") - did, err := syntax.ParseDID(didParam) + identParam := c.Param("ident") + + // if not a DID, try parsing as a handle and doing a redirect + if !strings.HasPrefix(identParam, "did:") { + handle, err := syntax.ParseHandle(identParam) + if err != nil { + return echo.NewHTTPError(400, fmt.Sprintf("not a valid handle: %s", identParam)) + } + + // check that public view is Ok, and resolve DID + pv, err := appbsky.ActorGetProfile(ctx, srv.xrpcc, handle.String()) + if err != nil { + return echo.NewHTTPError(404, fmt.Sprintf("account not found: %s", handle)) + } + for _, label := range pv.Labels { + if label.Src == pv.Did && label.Val == "!no-unauthenticated" { + return echo.NewHTTPError(403, fmt.Sprintf("account does not allow public views: %s", handle)) + } + } + return c.Redirect(http.StatusFound, fmt.Sprintf("/profile/%s/rss", pv.Did)) + } + + did, err := syntax.ParseDID(identParam) if err != nil { - return echo.NewHTTPError(400, fmt.Sprintf("not a valid DID: %s", didParam)) + return echo.NewHTTPError(400, fmt.Sprintf("not a valid DID: %s", identParam)) } // check that public view is Ok @@ -84,7 +107,7 @@ func (srv *Server) WebProfileRSS(c echo.Context) error { pubDate = createdAt.Time().Format(time.RFC822Z) } posts = append(posts, Item{ - Link: fmt.Sprintf("https://bsky.app/profile/%s/post/%s", pv.Handle, aturi.RecordKey().String()), + Link: fmt.Sprintf("https://%s/profile/%s/post/%s", req.Host, pv.Handle, aturi.RecordKey().String()), Description: rec.Text, PubDate: pubDate, GUID: ItemGUID{ @@ -105,7 +128,7 @@ func (srv *Server) WebProfileRSS(c echo.Context) error { feed := &rss{ Version: "2.0", Description: desc, - Link: fmt.Sprintf("https://bsky.app/profile/%s", pv.Handle), + Link: fmt.Sprintf("https://%s/profile/%s", req.Host, pv.Handle), Title: title, Item: posts, } diff --git a/bskyweb/cmd/bskyweb/server.go b/bskyweb/cmd/bskyweb/server.go index 5d9a481f..b0fde255 100644 --- a/bskyweb/cmd/bskyweb/server.go +++ b/bskyweb/cmd/bskyweb/server.go @@ -210,7 +210,7 @@ func serve(cctx *cli.Context) error { e.GET("/profile/:handle/feed/:rkey/liked-by", server.WebGeneric) // profile RSS feed (DID not handle) - e.GET("/profile/:did/rss", server.WebProfileRSS) + e.GET("/profile/:ident/rss", server.WebProfileRSS) // post endpoints; only first populates info e.GET("/profile/:handle/post/:rkey", server.WebPost) @@ -370,6 +370,7 @@ func (srv *Server) WebProfile(c echo.Context) error { req := c.Request() data["profileView"] = pv data["requestURI"] = fmt.Sprintf("https://%s%s", req.Host, req.URL.Path) + data["requestHost"] = req.Host return c.Render(http.StatusOK, "profile.html", data) } diff --git a/bskyweb/templates/profile.html b/bskyweb/templates/profile.html index 71c10032..551dc15a 100644 --- a/bskyweb/templates/profile.html +++ b/bskyweb/templates/profile.html @@ -34,7 +34,9 @@ {% endif %} - + {%- if requestHost %} + + {% endif %} {% endif -%} {%- endblock %}