Bluesky app fork with some witchin' additions 💫

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.

authored by bnewbold.net and committed by

GitHub b922b838 ee200927

+33 -7
+28 -5
bskyweb/cmd/bskyweb/rss.go
··· 4 4 "encoding/xml" 5 5 "fmt" 6 6 "net/http" 7 + "strings" 7 8 "time" 8 9 9 10 appbsky "github.com/bluesky-social/indigo/api/bsky" ··· 39 40 40 41 func (srv *Server) WebProfileRSS(c echo.Context) error { 41 42 ctx := c.Request().Context() 43 + req := c.Request() 42 44 43 - didParam := c.Param("did") 44 - did, err := syntax.ParseDID(didParam) 45 + identParam := c.Param("ident") 46 + 47 + // if not a DID, try parsing as a handle and doing a redirect 48 + if !strings.HasPrefix(identParam, "did:") { 49 + handle, err := syntax.ParseHandle(identParam) 50 + if err != nil { 51 + return echo.NewHTTPError(400, fmt.Sprintf("not a valid handle: %s", identParam)) 52 + } 53 + 54 + // check that public view is Ok, and resolve DID 55 + pv, err := appbsky.ActorGetProfile(ctx, srv.xrpcc, handle.String()) 56 + if err != nil { 57 + return echo.NewHTTPError(404, fmt.Sprintf("account not found: %s", handle)) 58 + } 59 + for _, label := range pv.Labels { 60 + if label.Src == pv.Did && label.Val == "!no-unauthenticated" { 61 + return echo.NewHTTPError(403, fmt.Sprintf("account does not allow public views: %s", handle)) 62 + } 63 + } 64 + return c.Redirect(http.StatusFound, fmt.Sprintf("/profile/%s/rss", pv.Did)) 65 + } 66 + 67 + did, err := syntax.ParseDID(identParam) 45 68 if err != nil { 46 - return echo.NewHTTPError(400, fmt.Sprintf("not a valid DID: %s", didParam)) 69 + return echo.NewHTTPError(400, fmt.Sprintf("not a valid DID: %s", identParam)) 47 70 } 48 71 49 72 // check that public view is Ok ··· 84 107 pubDate = createdAt.Time().Format(time.RFC822Z) 85 108 } 86 109 posts = append(posts, Item{ 87 - Link: fmt.Sprintf("https://bsky.app/profile/%s/post/%s", pv.Handle, aturi.RecordKey().String()), 110 + Link: fmt.Sprintf("https://%s/profile/%s/post/%s", req.Host, pv.Handle, aturi.RecordKey().String()), 88 111 Description: rec.Text, 89 112 PubDate: pubDate, 90 113 GUID: ItemGUID{ ··· 105 128 feed := &rss{ 106 129 Version: "2.0", 107 130 Description: desc, 108 - Link: fmt.Sprintf("https://bsky.app/profile/%s", pv.Handle), 131 + Link: fmt.Sprintf("https://%s/profile/%s", req.Host, pv.Handle), 109 132 Title: title, 110 133 Item: posts, 111 134 }
+2 -1
bskyweb/cmd/bskyweb/server.go
··· 210 210 e.GET("/profile/:handle/feed/:rkey/liked-by", server.WebGeneric) 211 211 212 212 // profile RSS feed (DID not handle) 213 - e.GET("/profile/:did/rss", server.WebProfileRSS) 213 + e.GET("/profile/:ident/rss", server.WebProfileRSS) 214 214 215 215 // post endpoints; only first populates info 216 216 e.GET("/profile/:handle/post/:rkey", server.WebPost) ··· 370 370 req := c.Request() 371 371 data["profileView"] = pv 372 372 data["requestURI"] = fmt.Sprintf("https://%s%s", req.Host, req.URL.Path) 373 + data["requestHost"] = req.Host 373 374 return c.Render(http.StatusOK, "profile.html", data) 374 375 } 375 376
+3 -1
bskyweb/templates/profile.html
··· 34 34 {% endif %} 35 35 <meta name="twitter:label1" content="Account DID"> 36 36 <meta name="twitter:value1" content="{{ profileView.Did }}"> 37 - <link rel="alternate" type="application/rss+xml" href="/profile/{{ profileView.Did }}/rss"> 37 + {%- if requestHost %} 38 + <link rel="alternate" type="application/rss+xml" href="https://{{ requestHost }}/profile/{{ profileView.Did }}/rss"> 39 + {% endif %} 38 40 {% endif -%} 39 41 {%- endblock %} 40 42