collection of golang services under the Red Dwarf umbrella server.reddwarf.app
bluesky reddwarf microcosm appview
15
fork

Configure Feed

Select the types of activity you want to include in your feed.

PostView ViewerState

+135 -17
+34
auth/auth.go
··· 211 211 span.End() 212 212 c.Next() 213 213 } 214 + 215 + func (auth *Auth) AuthenticateGinRequestViaJWTUnsafe(c *gin.Context) { 216 + tracer := otel.Tracer("auth") 217 + ctx, span := tracer.Start(c.Request.Context(), "Auth:AuthenticateGinRequestViaJWT") 218 + 219 + authHeader := c.GetHeader("Authorization") 220 + if authHeader == "" { 221 + span.End() 222 + c.Next() 223 + return 224 + } 225 + 226 + claims := jwt.StandardClaims{} 227 + 228 + err := auth.GetClaimsFromAuthHeader(ctx, authHeader, &claims) 229 + if err != nil { 230 + c.JSON(http.StatusUnauthorized, gin.H{"error": fmt.Errorf("Failed to get claims from auth header: %v", err).Error()}) 231 + span.End() 232 + c.Abort() 233 + return 234 + } 235 + 236 + // if claims.Audience != auth.ServiceDID { 237 + // c.JSON(http.StatusUnauthorized, gin.H{"error": fmt.Sprintf("Invalid audience (found '%s', expected '%s')", claims.Audience, auth.ServiceDID)}) 238 + // c.Abort() 239 + // return 240 + // } 241 + 242 + // Set claims Issuer to context as user DID 243 + c.Set("user_did", claims.Issuer) 244 + span.SetAttributes(attribute.String("user.did", claims.Issuer)) 245 + span.End() 246 + c.Next() 247 + }
+35 -13
main.go
··· 80 80 // spacedust is type definitions only 81 81 // jetstream types is probably available from jetstream/pkg/models 82 82 83 - r_unsafe := gin.New() 84 - r_unsafe.Use(gin.Logger()) 85 - r_unsafe.Use(gin.Recovery()) 86 - r_unsafe.Use(cors.Default()) 83 + router_raw := gin.New() 84 + router_raw.Use(gin.Logger()) 85 + router_raw.Use(gin.Recovery()) 86 + router_raw.Use(cors.Default()) 87 87 88 - r_unsafe.GET("/.well-known/did.json", GetWellKnownDID) 88 + router_raw.GET("/.well-known/did.json", GetWellKnownDID) 89 89 90 90 auther, err := auth.NewAuth( 91 91 100_000, ··· 97 97 log.Fatalf("Failed to create Auth: %v", err) 98 98 } 99 99 100 - router := r_unsafe.Group("/") 101 - router.Use(auther.AuthenticateGinRequestViaJWT) 100 + router := router_raw.Group("/") 102 101 router.Use(auther.AuthenticateGinRequestViaJWT) 102 + 103 + router_unsafe := router_raw.Group("/") 104 + router_unsafe.Use(auther.AuthenticateGinRequestViaJWTUnsafe) 103 105 104 106 responsewow, err := agnostic.RepoGetRecord(ctx, sl, "", "app.bsky.actor.profile", "did:web:did12.whey.party", "self") 105 107 if err != nil { ··· 227 229 labelerprofile, _, _ := appbskyactordefs.ProfileView(ctx, did, sl, BSKYIMAGECDN_URL) 228 230 labelerserviceresponse, _ := agnostic.RepoGetRecord(ctx, sl, "", "app.bsky.labeler.service", string(did), "self") 229 231 var labelerservice appbsky.LabelerService 230 - if err := json.Unmarshal(*labelerserviceresponse.Value, &labelerservice); err != nil { 231 - continue 232 + if labelerserviceresponse != nil { 233 + if err := json.Unmarshal(*labelerserviceresponse.Value, &labelerservice); err != nil { 234 + continue 235 + } 232 236 } 233 237 234 238 a := "account" ··· 380 384 381 385 router.GET("/xrpc/app.bsky.feed.getPosts", 382 386 func(c *gin.Context) { 387 + rawdid := c.GetString("user_did") 388 + var viewer *utils.DID 389 + didval, errdid := utils.NewDID(rawdid) 390 + if errdid != nil { 391 + viewer = nil 392 + } else { 393 + viewer = &didval 394 + } 383 395 postsreq := c.QueryArray("uris") 384 396 ctx := c.Request.Context() 385 397 ··· 396 408 go func(i int, raw string) { 397 409 defer wg.Done() 398 410 399 - post, _, _ := appbskyfeeddefs.PostView(ctx, raw, sl, cs, BSKYIMAGECDN_URL) 411 + post, _, _ := appbskyfeeddefs.PostView(ctx, raw, sl, cs, BSKYIMAGECDN_URL, viewer) 400 412 401 413 results[i].view = post 402 414 }(i, raw) ··· 417 429 }) 418 430 }) 419 431 420 - r_unsafe.GET("/xrpc/app.bsky.feed.getFeed", 432 + router_unsafe.GET("/xrpc/app.bsky.feed.getFeed", 421 433 func(c *gin.Context) { 422 434 ctx := c.Request.Context() 423 435 436 + rawdid := c.GetString("user_did") 437 + log.Println("getFeed router_unsafe user_did: " + rawdid) 438 + var viewer *utils.DID 439 + didval, errdid := utils.NewDID(rawdid) 440 + if errdid != nil { 441 + viewer = nil 442 + } else { 443 + viewer = &didval 444 + } 445 + 424 446 feedGenAturiRaw := c.Query("feed") 425 447 if feedGenAturiRaw == "" { 426 448 c.JSON(http.StatusBadRequest, gin.H{"error": "Missing feed param"}) ··· 515 537 skeletonposts, 516 538 20, 517 539 func(ctx context.Context, raw *appbsky.FeedDefs_SkeletonFeedPost) (*appbsky.FeedDefs_FeedViewPost, error) { 518 - post, _, err := appbskyfeeddefs.PostView(ctx, raw.Post, sl, cs, BSKYIMAGECDN_URL) 540 + post, _, err := appbskyfeeddefs.PostView(ctx, raw.Post, sl, cs, BSKYIMAGECDN_URL, viewer) 519 541 if err != nil { 520 542 return nil, err 521 543 } ··· 598 620 }(clientUUID) 599 621 } 600 622 }) 601 - r_unsafe.Run(":7152") 623 + router_raw.Run(":7152") 602 624 } 603 625 604 626 func getPostThreadV2(w http.ResponseWriter, r *http.Request) {
+1 -1
shims/lex/app/bsky/feed/defs/embed.go
··· 9 9 "tangled.org/whey.party/red-dwarf-server/shims/utils" 10 10 ) 11 11 12 - func PostView_Embed(ctx context.Context, postaturi string, feedPost *appbsky.FeedPost, sl *microcosm.MicrocosmClient, cs *microcosm.MicrocosmClient, imgcdn string) (*appbsky.FeedDefs_PostView_Embed, error) { 12 + func PostView_Embed(ctx context.Context, postaturi string, feedPost *appbsky.FeedPost, sl *microcosm.MicrocosmClient, cs *microcosm.MicrocosmClient, imgcdn string, viewer *utils.DID) (*appbsky.FeedDefs_PostView_Embed, error) { 13 13 if feedPost.Embed == nil { 14 14 return nil, nil 15 15 }
+50 -3
shims/lex/app/bsky/feed/defs/postview.go
··· 17 17 "tangled.org/whey.party/red-dwarf-server/shims/utils" 18 18 ) 19 19 20 - func PostView(ctx context.Context, postaturi string, sl *microcosm.MicrocosmClient, cs *microcosm.MicrocosmClient, imgcdn string) (*appbsky.FeedDefs_PostView, *appbsky.FeedPost, error) { 20 + func PostView(ctx context.Context, postaturi string, sl *microcosm.MicrocosmClient, cs *microcosm.MicrocosmClient, imgcdn string, viewer *utils.DID) (*appbsky.FeedDefs_PostView, *appbsky.FeedPost, error) { 21 21 aturi, err := syntax.ParseATURI(postaturi) 22 22 if err != nil { 23 23 return nil, nil, err ··· 39 39 if err := json.Unmarshal(*postRecordResponse.Value, &postRecord); err != nil { 40 40 return nil, nil, err 41 41 } 42 - postView_Embed, err := PostView_Embed(ctx, postaturi, &postRecord, sl, cs, imgcdn) 42 + postView_Embed, err := PostView_Embed(ctx, postaturi, &postRecord, sl, cs, imgcdn, viewer) 43 43 44 44 profile, _, _ := appbskyactordefs.ProfileViewBasic(ctx, repoDID, sl, imgcdn) 45 45 ··· 110 110 fakeCount, fakeCount, fakeCount, fakeCount, fakeCount, fakeCount 111 111 } 112 112 113 + var viewerState *appbsky.FeedDefs_ViewerState 114 + if viewer != nil { 115 + //log.Println("viewer is not nil: " + *viewer) 116 + did := []string{string(*viewer)} 117 + likeBacklinks, likeerr := constellation.GetBacklinks(ctx, cs, postaturi, "app.bsky.feed.like:subject.uri", did, nil, nil) 118 + repostBacklinks, reposterr := constellation.GetBacklinks(ctx, cs, postaturi, "app.bsky.feed.repost:subject.uri", did, nil, nil) 119 + if likeerr == nil && reposterr == nil { 120 + var likeATURI syntax.ATURI 121 + var repostATURI syntax.ATURI 122 + if likeBacklinks.Total > 0 { 123 + likeATURI, err = syntax.ParseATURI("at://" + likeBacklinks.Records[0].Did + "/" + likeBacklinks.Records[0].Collection + "/" + likeBacklinks.Records[0].Rkey) 124 + if err != nil { 125 + likeATURI = "" 126 + } 127 + } 128 + if repostBacklinks.Total > 0 { 129 + repostATURI, err = syntax.ParseATURI("at://" + repostBacklinks.Records[0].Did + "/" + repostBacklinks.Records[0].Collection + "/" + repostBacklinks.Records[0].Rkey) 130 + if err != nil { 131 + repostATURI = "" 132 + } 133 + } 134 + likelit := string(likeATURI) 135 + repostlit := string(repostATURI) 136 + var like *string = &likelit 137 + if likelit == "" { 138 + like = nil 139 + } 140 + var repost *string = &repostlit 141 + if repostlit == "" { 142 + repost = nil 143 + } 144 + viewerState = &appbsky.FeedDefs_ViewerState{ 145 + // Bookmarked *bool `json:"bookmarked,omitempty" cborgen:"bookmarked,omitempty"` 146 + // EmbeddingDisabled *bool `json:"embeddingDisabled,omitempty" cborgen:"embeddingDisabled,omitempty"` 147 + // Like *string `json:"like,omitempty" cborgen:"like,omitempty"` 148 + Like: like, 149 + // Pinned *bool `json:"pinned,omitempty" cborgen:"pinned,omitempty"` 150 + // ReplyDisabled *bool `json:"replyDisabled,omitempty" cborgen:"replyDisabled,omitempty"` 151 + // Repost *string `json:"repost,omitempty" cborgen:"repost,omitempty"` 152 + Repost: repost, 153 + // ThreadMuted *bool `json:"threadMuted,omitempty" cborgen:"threadMuted,omitempty"` 154 + } 155 + } 156 + } else { 157 + //log.Println("viewer is nil") 158 + } 159 + 113 160 return &appbsky.FeedDefs_PostView{ 114 161 // LexiconTypeID string `json:"$type" cborgen:"$type,const=app.bsky.feed.defs#postView"` 115 162 LexiconTypeID: "app.bsky.feed.defs#postView", ··· 139 186 // Uri string `json:"uri" cborgen:"uri"` 140 187 Uri: postRecordResponse.Uri, 141 188 // Viewer *FeedDefs_ViewerState `json:"viewer,omitempty" cborgen:"viewer,omitempty"` 142 - 189 + Viewer: viewerState, 143 190 }, &postRecord, nil 144 191 }
+15
utils.go
··· 5 5 "encoding/json" 6 6 "fmt" 7 7 "net/http" 8 + "net/http/httputil" 8 9 "strings" 9 10 "sync" 11 + 12 + "github.com/gin-gonic/gin" 10 13 ) 11 14 12 15 type DIDDocument struct { ··· 110 113 wg.Wait() 111 114 return errs 112 115 } 116 + 117 + func DebugMiddleware() gin.HandlerFunc { 118 + return func(c *gin.Context) { 119 + dump, err := httputil.DumpRequest(c.Request, true) 120 + if err == nil { 121 + fmt.Println("=== RAW REQUEST ===") 122 + fmt.Println(string(dump)) 123 + } 124 + 125 + c.Next() 126 + } 127 + }