Something went wrong. Try again.
Monorepo for the nibling.run platform
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081import { Client } from '@atcute/client';import type { ActorResolver } from '@atcute/identity-resolver';import type { Did } from '@atcute/lexicons';import { configureOAuth, createAuthorizationUrl, deleteStoredSession, finalizeAuthorization, getSession, OAuthUserAgent, type ClientAssertionFetcher, type Session as OAuthSession,} from '@atcute/oauth-browser-client';import { scopes } from './metadata.ts';import { config, resolveActor } from './identity.ts';import type { Session } from './session.ts';
export { scopes, clientMetadata, type ClientMetadata } from './metadata.ts';
export interface AuthOptions { clientId: string; redirectUri: string; /** Signs client assertions on the API worker, which makes nibling a confidential client (D19). */ fetchClientAssertion?: ClientAssertionFetcher;}
export function configureAuth({ clientId, redirectUri, fetchClientAssertion }: AuthOptions): void { configureOAuth({ metadata: { client_id: clientId, redirect_uri: redirectUri }, identityResolver, ...(fetchClientAssertion ? { fetchClientAssertion } : {}), });}
/** Sends the browser to the user's authorization server. The page unloads on success. */export async function signIn(identifier: string): Promise<void> { const actor = await resolveActor(identifier); const url = await createAuthorizationUrl({ target: { type: 'account', identifier: actor.handle ?? actor.did }, scope: scopes, }); window.location.assign(url);}
/** Exchanges the callback's query or fragment parameters for a session. */export async function completeSignIn(params: URLSearchParams): Promise<Session> { const { session } = await finalizeAuthorization(params); return toSession(session);}
/** The stored session for `did`, refreshed if needed, or undefined if there is none or it was revoked. */export async function resume(did: Did): Promise<Session | undefined> { try { return toSession(await getSession(did, { allowStale: true })); } catch { return undefined; }}
export async function signOut(did: Did): Promise<void> { if (config.viewer === did) config.viewer = null; try { await new OAuthUserAgent(await getSession(did, { allowStale: true })).signOut(); } catch { deleteStoredSession(did); }}
/** Also marks the account as the viewer, so reads of its own repo skip the gateway's cache. */function toSession(session: OAuthSession): Session { config.viewer = session.info.sub; return { did: session.info.sub, client: new Client({ handler: new OAuthUserAgent(session) }) };}
const identityResolver: ActorResolver = { async resolve(identifier) { const actor = await resolveActor(identifier); return { did: actor.did, handle: actor.handle ?? 'handle.invalid', pds: actor.pds }; },};