an app to share curated trails sidetrail.app
1

Configure Feed

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

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}