forked from
samuel.fm/statusphere-react
the statusphere demo reworked into a vite/react app in a monorepo
1import { AuthRequiredError } from '@atproto/xrpc-server'
2import { AppBskyActorProfile } from '@statusphere/lexicon'
3
4import { AppContext } from '#/context'
5import { Server } from '#/lexicons'
6import { bskyProfileToProfileView, statusToStatusView } from '#/lib/hydrate'
7import { getSessionAgent } from '#/session'
8
9export default function (server: Server, ctx: AppContext) {
10 server.xyz.statusphere.getUser({
11 handler: async ({ req, res }) => {
12 const agent = await getSessionAgent(req, res, ctx)
13 if (!agent) {
14 throw new AuthRequiredError('Authentication required')
15 }
16
17 const did = agent.assertDid
18
19 const profileResponse = await agent.com.atproto.repo
20 .getRecord({
21 repo: did,
22 collection: 'app.bsky.actor.profile',
23 rkey: 'self',
24 })
25 .catch(() => undefined)
26
27 const profileRecord = profileResponse?.data
28 let profile: AppBskyActorProfile.Record = {} as AppBskyActorProfile.Record
29
30 if (profileRecord && AppBskyActorProfile.isRecord(profileRecord.value)) {
31 const validated = AppBskyActorProfile.validateRecord(
32 profileRecord.value,
33 )
34 if (validated.success) {
35 profile = profileRecord.value
36 } else {
37 ctx.logger.error(
38 { err: validated.error },
39 'Failed to validate user profile',
40 )
41 }
42 }
43
44 // Fetch user status
45 const status = await ctx.db
46 .selectFrom('status')
47 .selectAll()
48 .where('authorDid', '=', did)
49 .orderBy('indexedAt', 'desc')
50 .executeTakeFirst()
51
52 return {
53 encoding: 'application/json',
54 body: {
55 profile: await bskyProfileToProfileView(did, profile, ctx),
56 status: status ? await statusToStatusView(status, ctx) : undefined,
57 },
58 }
59 },
60 })
61}