Add logoutCurrentAccount()

This commit is contained in:
Dan Abramov
2024-08-15 01:19:34 +01:00
parent eded090ca8
commit 10a6a5fd24
4 changed files with 144 additions and 1 deletions
@@ -674,6 +674,103 @@ describe('session', () => {
expect(state.currentAgentState.did).toBe(undefined)
})
it('can log out of the current account', () => {
let state = getInitialState([])
const agent1 = new BskyAgent({service: 'https://alice.com'})
agent1.sessionManager.session = {
active: true,
did: 'alice-did',
handle: 'alice.test',
accessJwt: 'alice-access-jwt-1',
refreshJwt: 'alice-refresh-jwt-1',
}
state = run(state, [
{
type: 'switched-to-account',
newAgent: agent1,
newAccount: agentToSessionAccountOrThrow(agent1),
},
])
expect(state.accounts.length).toBe(1)
expect(state.accounts[0].accessJwt).toBe('alice-access-jwt-1')
expect(state.accounts[0].refreshJwt).toBe('alice-refresh-jwt-1')
expect(state.currentAgentState.did).toBe('alice-did')
const agent2 = new BskyAgent({service: 'https://bob.com'})
agent2.sessionManager.session = {
active: true,
did: 'bob-did',
handle: 'bob.test',
accessJwt: 'bob-access-jwt-1',
refreshJwt: 'bob-refresh-jwt-1',
}
state = run(state, [
{
type: 'switched-to-account',
newAgent: agent2,
newAccount: agentToSessionAccountOrThrow(agent2),
},
])
expect(state.accounts.length).toBe(2)
expect(state.accounts[0].accessJwt).toBe('bob-access-jwt-1')
expect(state.accounts[0].refreshJwt).toBe('bob-refresh-jwt-1')
expect(state.currentAgentState.did).toBe('bob-did')
state = run(state, [
{
type: 'logged-out-current-account',
},
])
expect(state.accounts.length).toBe(2)
expect(state.accounts[0].accessJwt).toBe(undefined)
expect(state.accounts[0].refreshJwt).toBe(undefined)
expect(state.accounts[1].accessJwt).toBe('alice-access-jwt-1')
expect(state.accounts[1].refreshJwt).toBe('alice-refresh-jwt-1')
expect(state.currentAgentState.did).toBe(undefined)
expect(printState(state)).toMatchInlineSnapshot(`
{
"accounts": [
{
"accessJwt": undefined,
"active": true,
"did": "bob-did",
"email": undefined,
"emailAuthFactor": false,
"emailConfirmed": false,
"handle": "bob.test",
"pdsUrl": undefined,
"refreshJwt": undefined,
"service": "https://bob.com/",
"signupQueued": false,
"status": undefined,
},
{
"accessJwt": "alice-access-jwt-1",
"active": true,
"did": "alice-did",
"email": undefined,
"emailAuthFactor": false,
"emailConfirmed": false,
"handle": "alice.test",
"pdsUrl": undefined,
"refreshJwt": "alice-refresh-jwt-1",
"service": "https://alice.com/",
"signupQueued": false,
"status": undefined,
},
],
"currentAgentState": {
"agent": {
"service": "https://public.api.bsky.app/",
},
"did": undefined,
},
"needsPersist": true,
}
`)
})
it('updates stored account with refreshed tokens', () => {
let state = getInitialState([])
+25 -1
View File
@@ -35,6 +35,7 @@ const AgentContext = React.createContext<BskyAgent | null>(null)
const ApiContext = React.createContext<SessionApiContext>({
createAccount: async () => {},
login: async () => {},
logoutCurrentAccount: async () => {},
logoutEveryAccount: async () => {},
resumeSession: async () => {},
removeAccount: () => {},
@@ -115,6 +116,21 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
[onAgentSessionChange, cancelPendingTask],
)
const logoutCurrentAccount = React.useCallback<
SessionApiContext['logoutEveryAccount']
>(
logContext => {
addSessionDebugLog({type: 'method:start', method: 'logout'})
cancelPendingTask()
dispatch({
type: 'logged-out-current-account',
})
logEvent('account:loggedOut', {logContext, scope: 'current'})
addSessionDebugLog({type: 'method:end', method: 'logout'})
},
[cancelPendingTask],
)
const logoutEveryAccount = React.useCallback<
SessionApiContext['logoutEveryAccount']
>(
@@ -232,11 +248,19 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
() => ({
createAccount,
login,
logoutCurrentAccount,
logoutEveryAccount,
resumeSession,
removeAccount,
}),
[createAccount, login, logoutEveryAccount, resumeSession, removeAccount],
[
createAccount,
login,
logoutCurrentAccount,
logoutEveryAccount,
resumeSession,
removeAccount,
],
)
// @ts-ignore
+19
View File
@@ -41,6 +41,9 @@ export type Action =
type: 'removed-account'
accountDid: string
}
| {
type: 'logged-out-current-account'
}
| {
type: 'logged-out-every-account'
}
@@ -138,6 +141,22 @@ let reducer = (state: State, action: Action): State => {
needsPersist: true,
}
}
case 'logged-out-current-account': {
const {currentAgentState} = state
return {
accounts: state.accounts.map(a =>
a.did === currentAgentState.did
? {
...a,
refreshJwt: undefined,
accessJwt: undefined,
}
: a,
),
currentAgentState: createPublicAgentState(),
needsPersist: true,
}
}
case 'logged-out-every-account': {
return {
accounts: state.accounts.map(a => ({
+3
View File
@@ -29,6 +29,9 @@ export type SessionApiContext = {
},
logContext: LogEvents['account:loggedIn']['logContext'],
) => Promise<void>
logoutCurrentAccount: (
logContext: LogEvents['account:loggedOut']['logContext'],
) => void
logoutEveryAccount: (
logContext: LogEvents['account:loggedOut']['logContext'],
) => void