diff options
author | dan <dan.abramov@gmail.com> | 2023-12-06 18:32:14 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-06 18:32:14 +0000 |
commit | 748212e000f963976bca5d63e0961d75a7e8b296 (patch) | |
tree | 8c18872d5f18358cf131d5ea506f4a98a8c26cdd /src | |
parent | 20a46c8cffd53869559c70b41e04ba1755bf560c (diff) | |
download | voidsky-748212e000f963976bca5d63e0961d75a7e8b296.tar.zst |
Remove getSession waterfall (#2112)
Diffstat (limited to 'src')
-rw-r--r-- | src/state/session/index.tsx | 78 |
1 files changed, 55 insertions, 23 deletions
diff --git a/src/state/session/index.tsx b/src/state/session/index.tsx index 0d52d2521..49c1326d9 100644 --- a/src/state/session/index.tsx +++ b/src/state/session/index.tsx @@ -1,6 +1,7 @@ import React from 'react' import {BskyAgent, AtpPersistSessionHandler} from '@atproto/api' import {useQueryClient} from '@tanstack/react-query' +import {jwtDecode} from 'jwt-decode' import {networkRetry} from '#/lib/async/retry' import {logger} from '#/logger' @@ -327,34 +328,65 @@ export function Provider({children}: React.PropsWithChildren<{}>) { ), }) - await networkRetry(3, () => - agent.resumeSession({ - accessJwt: account.accessJwt || '', - refreshJwt: account.refreshJwt || '', - did: account.did, - handle: account.handle, - }), - ) + let canReusePrevSession = false + try { + if (account.accessJwt) { + const decoded = jwtDecode(account.accessJwt) + if (decoded.exp) { + const didExpire = Date.now() >= decoded.exp * 1000 + if (!didExpire) { + canReusePrevSession = true + } + } + } + } catch (e) { + console.error('Could not decode jwt.') + } - if (!agent.session) { - throw new Error(`session: initSession failed to establish a session`) + const prevSession = { + accessJwt: account.accessJwt || '', + refreshJwt: account.refreshJwt || '', + did: account.did, + handle: account.handle, } - // ensure changes in handle/email etc are captured on reload - const freshAccount: SessionAccount = { - service: agent.service.toString(), - did: agent.session.did, - handle: agent.session.handle, - email: agent.session.email, - emailConfirmed: agent.session.emailConfirmed || false, - refreshJwt: agent.session.refreshJwt, - accessJwt: agent.session.accessJwt, + if (canReusePrevSession) { + agent.session = prevSession + __globalAgent = agent + queryClient.clear() + upsertAccount(account) + emitSessionLoaded(account, agent) + // Intentionally not awaited to unblock the UI: + resumeSessionWithFreshAccount().then(async freshAccount => { + if (JSON.stringify(account) !== JSON.stringify(freshAccount)) { + upsertAccount(freshAccount) + emitSessionLoaded(freshAccount, agent) + } + }) + } else { + const freshAccount = await resumeSessionWithFreshAccount() + __globalAgent = agent + queryClient.clear() + upsertAccount(freshAccount) + emitSessionLoaded(freshAccount, agent) } - __globalAgent = agent - queryClient.clear() - upsertAccount(freshAccount) - emitSessionLoaded(freshAccount, agent) + async function resumeSessionWithFreshAccount(): Promise<SessionAccount> { + await networkRetry(3, () => agent.resumeSession(prevSession)) + if (!agent.session) { + throw new Error(`session: initSession failed to establish a session`) + } + // ensure changes in handle/email etc are captured on reload + return { + service: agent.service.toString(), + did: agent.session.did, + handle: agent.session.handle, + email: agent.session.email, + emailConfirmed: agent.session.emailConfirmed || false, + refreshJwt: agent.session.refreshJwt, + accessJwt: agent.session.accessJwt, + } + } }, [upsertAccount, queryClient], ) |