an app to share curated trails sidetrail.app
atproto nextjs react rsc
50
fork

Configure Feed

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

at main 64 lines 2.1 kB view raw
1import "server-only"; 2import { Client } from "@atproto/lex"; 3import { IdResolver } from "@atproto/identity"; 4import { TokenRefreshError } from "@atproto/oauth-client"; 5import { refresh } from "next/cache"; 6import { getSession } from "@/auth/session"; 7import { getOAuthClient } from "@/auth/client"; 8 9const idResolver = new IdResolver(); 10 11export class AuthRequiredError extends Error { 12 constructor(message = "Authentication required") { 13 super(message); 14 this.name = "AuthRequiredError"; 15 } 16} 17 18/** 19 * Get an unauthenticated lex Client for reading from a user's PDS. 20 * Resolves the DID to find the PDS endpoint, then creates a client that hits it directly. 21 * Use this for read-only operations to avoid OAuth client's CachedGetter issues with "use cache". 22 */ 23export async function getPublicLexClient(did: string): Promise<Client> { 24 const atprotoData = await idResolver.did.resolveAtprotoData(did); 25 const pdsUrl = atprotoData.pds; 26 return new Client(pdsUrl); 27} 28 29/** 30 * Get an authenticated lex Client for the current user. 31 * Throws AuthRequiredError if not authenticated. 32 * If the OAuth session is invalid/deleted, clears the cookie and throws AuthRequiredError. 33 */ 34export async function getLexClient(): Promise<Client> { 35 const session = await getSession(); 36 if (!session.did) { 37 throw new AuthRequiredError(); 38 } 39 40 const oauthClient = await getOAuthClient(); 41 42 let oauthSession; 43 try { 44 oauthSession = await oauthClient.restore(session.did); 45 } catch (err) { 46 if (err instanceof TokenRefreshError) { 47 const cause = err.cause instanceof Error ? err.cause.message : err.cause; 48 console.log(`[auth] TokenRefreshError ${session.did}: ${err.message} (cause: ${cause})`); 49 session.destroy(); 50 refresh(); 51 } else { 52 const msg = err instanceof Error ? err.message : err; 53 console.log(`[auth] restore failed ${session.did}: ${msg}`); 54 } 55 throw err; 56 } 57 58 if (!oauthSession) { 59 throw new AuthRequiredError(); 60 } 61 62 // Create lex Client directly from OAuth session (idiomatic usage) 63 return new Client(oauthSession); 64}