Add logoutCurrentAccount()
This commit is contained in:
@@ -674,6 +674,103 @@ describe('session', () => {
|
|||||||
expect(state.currentAgentState.did).toBe(undefined)
|
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', () => {
|
it('updates stored account with refreshed tokens', () => {
|
||||||
let state = getInitialState([])
|
let state = getInitialState([])
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ const AgentContext = React.createContext<BskyAgent | null>(null)
|
|||||||
const ApiContext = React.createContext<SessionApiContext>({
|
const ApiContext = React.createContext<SessionApiContext>({
|
||||||
createAccount: async () => {},
|
createAccount: async () => {},
|
||||||
login: async () => {},
|
login: async () => {},
|
||||||
|
logoutCurrentAccount: async () => {},
|
||||||
logoutEveryAccount: async () => {},
|
logoutEveryAccount: async () => {},
|
||||||
resumeSession: async () => {},
|
resumeSession: async () => {},
|
||||||
removeAccount: () => {},
|
removeAccount: () => {},
|
||||||
@@ -115,6 +116,21 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||||||
[onAgentSessionChange, cancelPendingTask],
|
[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<
|
const logoutEveryAccount = React.useCallback<
|
||||||
SessionApiContext['logoutEveryAccount']
|
SessionApiContext['logoutEveryAccount']
|
||||||
>(
|
>(
|
||||||
@@ -232,11 +248,19 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||||||
() => ({
|
() => ({
|
||||||
createAccount,
|
createAccount,
|
||||||
login,
|
login,
|
||||||
|
logoutCurrentAccount,
|
||||||
logoutEveryAccount,
|
logoutEveryAccount,
|
||||||
resumeSession,
|
resumeSession,
|
||||||
removeAccount,
|
removeAccount,
|
||||||
}),
|
}),
|
||||||
[createAccount, login, logoutEveryAccount, resumeSession, removeAccount],
|
[
|
||||||
|
createAccount,
|
||||||
|
login,
|
||||||
|
logoutCurrentAccount,
|
||||||
|
logoutEveryAccount,
|
||||||
|
resumeSession,
|
||||||
|
removeAccount,
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ export type Action =
|
|||||||
type: 'removed-account'
|
type: 'removed-account'
|
||||||
accountDid: string
|
accountDid: string
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
type: 'logged-out-current-account'
|
||||||
|
}
|
||||||
| {
|
| {
|
||||||
type: 'logged-out-every-account'
|
type: 'logged-out-every-account'
|
||||||
}
|
}
|
||||||
@@ -138,6 +141,22 @@ let reducer = (state: State, action: Action): State => {
|
|||||||
needsPersist: true,
|
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': {
|
case 'logged-out-every-account': {
|
||||||
return {
|
return {
|
||||||
accounts: state.accounts.map(a => ({
|
accounts: state.accounts.map(a => ({
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ export type SessionApiContext = {
|
|||||||
},
|
},
|
||||||
logContext: LogEvents['account:loggedIn']['logContext'],
|
logContext: LogEvents['account:loggedIn']['logContext'],
|
||||||
) => Promise<void>
|
) => Promise<void>
|
||||||
|
logoutCurrentAccount: (
|
||||||
|
logContext: LogEvents['account:loggedOut']['logContext'],
|
||||||
|
) => void
|
||||||
logoutEveryAccount: (
|
logoutEveryAccount: (
|
||||||
logContext: LogEvents['account:loggedOut']['logContext'],
|
logContext: LogEvents['account:loggedOut']['logContext'],
|
||||||
) => void
|
) => void
|
||||||
|
|||||||
Reference in New Issue
Block a user