import type { Did } from "@atcute/lexicons/syntax"; import { OAuthUserAgent, deleteStoredSession, getSession, type Session } from "@atcute/oauth-browser-client"; import { forgetOrgDid, loadOrgControllers, loadOrgDids, orgDidsControlledBy } from "$lib/auth/accounts"; // org sessions are minted from a controller's session and are useless to the // user once that controller signs out, so they get revoked alongside it export interface OrgSessionDependencies { loadOrgDids: () => Did[]; loadOrgControllers: () => Record; getSession: (sub: Did, options?: { allowStale?: boolean }) => Promise; createAgent: (session: Session) => Pick; deleteStoredSession: (sub: Did) => void; forgetOrgDid: (did: Did) => void; } const defaultDependencies: OrgSessionDependencies = { loadOrgDids, loadOrgControllers, getSession, createAgent: (session) => new OAuthUserAgent(session), deleteStoredSession, forgetOrgDid }; const revokeOne = async (orgDid: Did, deps: OrgSessionDependencies): Promise => { try { // allowStale skips a refresh, the token is about to be revoked anyway const session = await deps.getSession(orgDid, { allowStale: true }); await deps.createAgent(session).signOut(); } catch { // nothing to revoke, or the pds refused, either way drop the local copy deps.deleteStoredSession(orgDid); } deps.forgetOrgDid(orgDid); }; const revoke = async (orgDids: Did[], deps: OrgSessionDependencies): Promise => { await Promise.allSettled(orgDids.map((orgDid) => revokeOne(orgDid, deps))); }; export const revokeOrgSessionsFor = ( controllerDid: Did, deps: OrgSessionDependencies = defaultDependencies ): Promise => revoke(orgDidsControlledBy(deps.loadOrgControllers(), controllerDid), deps); export const revokeAllOrgSessions = ( deps: OrgSessionDependencies = defaultDependencies ): Promise => revoke(deps.loadOrgDids(), deps);