refreshSession
uses tcmts.atproto.jwtExpiry, which uses Buffer
Refresh a sign-in's tokens (and keep them): false when they can't be (expired, or revoked). An app password's are refreshed with its refresh token, or else it signs in again with the password.
import { dpopFetch, jwtExpiry, keepSession, passwordSignIn } from "#codebase/tcmts/atproto"; import type { OAuthSession, TokenAnswer } from "#codebase/tcmts/atproto"; export async function refreshSession(s: OAuthSession): Promise<boolean> { if (s.appPassword !== undefined) { let next: { accessJwt: string; refreshJwt: string; did: string } | undefined; if (s.refreshToken) { const res = await fetch(s.tokenEndpoint, { method: "POST", headers: { authorization: `Bearer ${s.refreshToken}` }, }); if (res.ok) next = (await res.json()) as typeof next; } if (next && next.did === s.did) { s.accessToken = next.accessJwt; s.refreshToken = next.refreshJwt; s.expiresAt = jwtExpiry(next.accessJwt); } else { let again: OAuthSession; try { again = await passwordSignIn(s.did, s.appPassword); } catch { return false; } Object.assign(s, again); } keepSession(s.did, s); return true; } if (!s.refreshToken || !s.dpopKey) return false; const res = await dpopFetch(s.dpopKey, s.tokenEndpoint, { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ grant_type: "refresh_token", refresh_token: s.refreshToken, client_id: s.clientId, }).toString(), }); if (!res.ok) return false; const t = (await res.json()) as TokenAnswer; if (t.sub !== s.did) return false; s.accessToken = t.access_token; if (t.refresh_token) s.refreshToken = t.refresh_token; s.expiresAt = Date.now() + (t.expires_in ?? 300) * 1000; if (t.scope) s.scope = t.scope; keepSession(s.did, s); return true; }
uses
- tcmts.atproto.OAuthSession
- tcmts.atproto.TokenAnswer
- tcmts.atproto.dpopFetch
- tcmts.atproto.jwtExpiry
- tcmts.atproto.keepSession
- tcmts.atproto.passwordSignIn