Skip to content

Commit d7b5184

Browse files
committed
add get avatar to fall back on atproto.get. cleanup
1 parent 0f87189 commit d7b5184

File tree

3 files changed

+41
-32
lines changed

3 files changed

+41
-32
lines changed

server/api/auth/atproto.get.ts

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,38 @@ import { handleResolver } from '#server/utils/atproto/oauth'
1010
import { type AtIdentifierString, Client } from '@atproto/lex'
1111
import * as app from '#shared/types/lexicons/app'
1212

13+
/**
14+
* Fetch the user's profile record to get their avatar blob reference
15+
* @param did
16+
* @param pds
17+
* @returns
18+
*/
19+
async function getAvatar(did: string, pds: string) {
20+
let avatar: string | undefined
21+
try {
22+
const pdsUrl = new URL(pds)
23+
// Only fetch from HTTPS PDS endpoints to prevent SSRF
24+
if (did && pdsUrl.protocol === 'https:') {
25+
const client = new Client(pdsUrl)
26+
const profileResponse = await client.get(app.bsky.actor.profile, {
27+
// Hack for now need to find an example on how to use it properly
28+
repo: did as AtIdentifierString,
29+
rkey: 'self',
30+
})
31+
32+
const validatedResponse = app.bsky.actor.profile.main.validate(profileResponse.value)
33+
34+
if (validatedResponse.avatar?.ref) {
35+
// Use Bluesky CDN for faster image loading
36+
avatar = `https://cdn.bsky.app/img/feed_thumbnail/plain/${did}/${validatedResponse.avatar?.ref}@jpeg`
37+
}
38+
}
39+
} catch {
40+
// Avatar fetch failed, continue without it
41+
}
42+
return avatar
43+
}
44+
1345
export default defineEventHandler(async event => {
1446
const config = useRuntimeConfig(event)
1547
if (!config.sessionPassword) {
@@ -72,30 +104,7 @@ export default defineEventHandler(async event => {
72104
if (response.ok) {
73105
const miniDoc: PublicUserSession = await response.json()
74106

75-
// Fetch the user's profile record to get their avatar blob reference
76-
let avatar: string | undefined
77-
const did = agent.did
78-
try {
79-
const pdsUrl = new URL(miniDoc.pds)
80-
// Only fetch from HTTPS PDS endpoints to prevent SSRF
81-
if (did && pdsUrl.protocol === 'https:') {
82-
const client = new Client(pdsUrl)
83-
const profileResponse = await client.get(app.bsky.actor.profile, {
84-
// Hack for now need to find an example on how to use it properly
85-
repo: did as AtIdentifierString,
86-
rkey: 'self',
87-
})
88-
89-
const validatedResponse = app.bsky.actor.profile.main.validate(profileResponse.value)
90-
91-
if (validatedResponse.avatar?.ref) {
92-
// Use Bluesky CDN for faster image loading
93-
avatar = `https://cdn.bsky.app/img/feed_thumbnail/plain/${did}/${validatedResponse.avatar?.ref}@jpeg`
94-
}
95-
}
96-
} catch {
97-
// Avatar fetch failed, continue without it
98-
}
107+
let avatar: string | undefined = await getAvatar(authSession.did, miniDoc.pds)
99108

100109
await session.update({
101110
public: {
@@ -106,14 +115,15 @@ export default defineEventHandler(async event => {
106115
} else {
107116
//If slingshot fails we still want to set some key info we need.
108117
const pdsBase = (await authSession.getTokenInfo()).aud
118+
let avatar: string | undefined = await getAvatar(authSession.did, pdsBase)
109119
await session.update({
110120
public: {
111121
did: authSession.did,
112122
handle: 'Not available',
113123
pds: pdsBase,
124+
avatar,
114125
},
115126
})
116127
}
117-
118128
return sendRedirect(event, '/')
119129
})

server/utils/atproto/oauth-session-store.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@ export class OAuthSessionStore implements NodeSavedSessionStore {
1717

1818
async set(_key: string, val: NodeSavedSession) {
1919
// We are ignoring the key since the mapping is already done in the session
20-
console.log('New set expires:', val.tokenSet.expires_at)
2120
try {
2221
await this.session.update({
2322
oauthSession: val,
2423
})
2524
} catch (error) {
26-
console.error('Error setting OAuth session:', error)
25+
// Not sure if this has been happening. But helps with debugging
26+
console.error(
27+
'[oauth session store] Failed to set session:',
28+
error instanceof Error ? error.message : 'Unknown error',
29+
)
2730
}
2831
}
2932

server/utils/atproto/oauth.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,8 @@ async function getOAuthSession(
6767
})
6868

6969
const currentSession = serverSession.data
70-
if (!currentSession) {
71-
console.log('oauth session not found')
72-
return { oauthSession: undefined, serverSession }
73-
}
70+
if (!currentSession) return { oauthSession: undefined, serverSession }
7471

75-
// restore using the subject
7672
const oauthSession = await client.restore(currentSession.public.did)
7773
return { oauthSession, serverSession }
7874
} catch (error) {

0 commit comments

Comments
 (0)