import type { OAuthSession } from "@atproto/oauth-client-node"; import type { AppContext } from "./app-context.js"; import type { CookieSession } from "./cookie-session-store.js"; /** * Result of restoring an OAuth session from a cookie token. */ export interface RestoredSession { oauthSession: OAuthSession; cookieSession: CookieSession; } /** * Restore an OAuth session from a cookie token. * * Looks up the cookie token in the CookieSessionStore, then restores * the OAuth session from the library's session store (with automatic * token refresh). * * Returns both the OAuth session and cookie session if successful, * allowing callers to access handle and other cookie metadata without * redundant store queries. * * Returns null if the cookie session doesn't exist, is expired, * or the OAuth session is not found (expected cases). * Throws on unexpected errors (network failures, etc.) that should bubble up. */ export async function restoreOAuthSession( ctx: AppContext, cookieToken: string ): Promise { const cookieSession = ctx.cookieSessionStore.get(cookieToken); if (!cookieSession) { return null; } try { // Restore OAuth session from library's session store // This will automatically refresh tokens if needed const oauthSession = await ctx.oauthClient.restore(cookieSession.did); if (!oauthSession) { return null; } return { oauthSession, cookieSession }; } catch (error) { // Check if this is an expected "session not found" error if (error instanceof Error && error.message.includes("not found")) { return null; } // Unexpected error - log and re-throw ctx.logger.error("Unexpected error restoring OAuth session", { operation: "restoreOAuthSession", did: cookieSession.did, error: error instanceof Error ? error.message : String(error), }); throw error; } }