forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
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 try {
18 const sessData = jwtDecode(accessJwt)
19 return (
20 hasProp(sessData, 'scope') &&
21 sessData.scope === 'com.atproto.signupQueued'
22 )
23 } catch {
24 return false
25 }
26 }
27 return false
28}
29
30export function isSessionExpired(account: SessionAccount) {
31 if (account.accessJwt) {
32 return isJwtExpired(account.accessJwt)
33 } else {
34 return true
35 }
36}
37
38/**
39 * Creates and attempted to resumeSession for every stored session.
40 * Intended to be used to send push token revokations just before logout.
41 */
42export async function createTemporaryAgentsAndResume(
43 accounts: SessionAccount[],
44) {
45 const agents = await Promise.allSettled(
46 accounts.map(async account => {
47 const agent: AtpAgent = new AtpAgent({service: account.service})
48 if (account.pdsUrl) {
49 agent.sessionManager.pdsUrl = new URL(account.pdsUrl)
50 }
51
52 const session = sessionAccountToSession(account)
53 const res = await agent.resumeSession(session)
54 if (!res.success) throw new Error('Failed to resume session')
55
56 agent.assertAuthenticated() // confirm auth success
57
58 return agent
59 }),
60 )
61
62 return agents
63 .filter(x => x.status === 'fulfilled')
64 .map(promise => promise.value)
65}