Bluesky app fork with some witchin' additions 馃挮 witchsky.app
bluesky fork client
at main 61 lines 1.7 kB view raw
1import AtpAgent from '@atproto/api' 2import {jwtDecode} from 'jwt-decode' 3 4import {isJwtExpired} from '#/lib/jwt' 5import {hasProp} from '#/lib/type-guards' 6import * as persisted from '#/state/persisted' 7import {sessionAccountToSession} from './agent' 8import {type SessionAccount} from './types' 9 10export function readLastActiveAccount() { 11 const {currentAccount, accounts} = persisted.get('session') 12 return accounts.find(a => a.did === currentAccount?.did) 13} 14 15export function isSignupQueued(accessJwt: string | undefined) { 16 if (accessJwt) { 17 const sessData = jwtDecode(accessJwt) 18 return ( 19 hasProp(sessData, 'scope') && 20 sessData.scope === 'com.atproto.signupQueued' 21 ) 22 } 23 return false 24} 25 26export function isSessionExpired(account: SessionAccount) { 27 if (account.accessJwt) { 28 return isJwtExpired(account.accessJwt) 29 } else { 30 return true 31 } 32} 33 34/** 35 * Creates and attempted to resumeSession for every stored session. 36 * Intended to be used to send push token revokations just before logout. 37 */ 38export async function createTemporaryAgentsAndResume( 39 accounts: SessionAccount[], 40) { 41 const agents = await Promise.allSettled( 42 accounts.map(async account => { 43 const agent: AtpAgent = new AtpAgent({service: account.service}) 44 if (account.pdsUrl) { 45 agent.sessionManager.pdsUrl = new URL(account.pdsUrl) 46 } 47 48 const session = sessionAccountToSession(account) 49 const res = await agent.resumeSession(session) 50 if (!res.success) throw new Error('Failed to resume session') 51 52 agent.assertAuthenticated() // confirm auth success 53 54 return agent 55 }), 56 ) 57 58 return agents 59 .filter(x => x.status === 'fulfilled') 60 .map(promise => promise.value) 61}