This repository has no description
0

Configure Feed

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

appview/oauth: create tangled profile on first login

Creates an empty sh.tangled.actor.profile on first login. This should
prevent profile picture uploads from breaking due to profile record
existing beforehand.

This should also allow for us to estimate total users better globally.

Signed-off-by: Anirudh Oppiliappan <anirudh@tangled.org>

author
Anirudh Oppiliappan
committer did:plc:wshs7t2adsemcrrd4snkeq… date (Jan 26, 2026, 6:44 AM UTC) commit b217e460 parent 2e71ee92 change-id ntktzrry
+52
+52
appview/oauth/handler.go
··· 10 10 "slices" 11 11 "time" 12 12 13 + comatproto "github.com/bluesky-social/indigo/api/atproto" 13 14 "github.com/bluesky-social/indigo/atproto/auth/oauth" 15 + lexutil "github.com/bluesky-social/indigo/lex/util" 14 16 "github.com/go-chi/chi/v5" 15 17 "github.com/posthog/posthog-go" 16 18 "tangled.org/core/api/tangled" 17 19 "tangled.org/core/appview/db" 20 + "tangled.org/core/appview/models" 18 21 "tangled.org/core/consts" 19 22 "tangled.org/core/orm" 20 23 "tangled.org/core/tid" ··· 82 85 } 83 86 84 87 o.Logger.Debug("session saved successfully") 88 + 85 89 go o.addToDefaultKnot(sessData.AccountDID.String()) 86 90 go o.addToDefaultSpindle(sessData.AccountDID.String()) 91 + go o.ensureTangledProfile(sessData) 87 92 88 93 if !o.Config.Core.Dev { 89 94 err = o.Posthog.Enqueue(posthog.Capture{ ··· 187 192 } 188 193 189 194 l.Debug("successfully addeds to default Knot") 195 + } 196 + 197 + func (o *OAuth) ensureTangledProfile(sessData *oauth.ClientSessionData) { 198 + ctx := context.Background() 199 + did := sessData.AccountDID.String() 200 + l := o.Logger.With("did", did) 201 + 202 + _, err := db.GetProfile(o.Db, did) 203 + if err == nil { 204 + l.Debug("profile already exists in DB") 205 + return 206 + } 207 + 208 + l.Debug("creating empty Tangled profile") 209 + 210 + sess, err := o.ClientApp.ResumeSession(ctx, sessData.AccountDID, sessData.SessionID) 211 + if err != nil { 212 + l.Error("failed to resume session for profile creation", "err", err) 213 + return 214 + } 215 + client := sess.APIClient() 216 + 217 + _, err = comatproto.RepoPutRecord(ctx, client, &comatproto.RepoPutRecord_Input{ 218 + Collection: tangled.ActorProfileNSID, 219 + Repo: did, 220 + Rkey: "self", 221 + Record: &lexutil.LexiconTypeDecoder{Val: &tangled.ActorProfile{}}, 222 + }) 223 + 224 + if err != nil { 225 + l.Error("failed to create empty profile on PDS", "err", err) 226 + return 227 + } 228 + 229 + tx, err := o.Db.BeginTx(ctx, nil) 230 + if err != nil { 231 + l.Error("failed to start transaction", "err", err) 232 + return 233 + } 234 + 235 + emptyProfile := &models.Profile{Did: did} 236 + if err := db.UpsertProfile(tx, emptyProfile); err != nil { 237 + l.Error("failed to create empty profile in DB", "err", err) 238 + return 239 + } 240 + 241 + l.Debug("successfully created empty Tangled profile on PDS and DB") 190 242 } 191 243 192 244 // create a session using apppasswords