[Session] Persist updates from inactive agent

zio/stable
Dan Abramov 2024-05-23 02:09:17 +01:00 committed by dan
parent 03655abb7c
commit acf1def6c1
2 changed files with 22 additions and 17 deletions

View File

@ -872,7 +872,7 @@ describe('session', () => {
expect(state.accounts[0].accessJwt).toBe('alice-access-jwt-3') expect(state.accounts[0].accessJwt).toBe('alice-access-jwt-3')
}) })
it('ignores updates from a stale agent', () => { it('accepts updates from a stale agent', () => {
let state = getInitialState([]) let state = getInitialState([])
const agent1 = new BskyAgent({service: 'https://alice.com'}) const agent1 = new BskyAgent({service: 'https://alice.com'})
@ -928,10 +928,10 @@ describe('session', () => {
]) ])
expect(state.accounts.length).toBe(2) expect(state.accounts.length).toBe(2)
expect(state.accounts[1].did).toBe('alice-did') expect(state.accounts[1].did).toBe('alice-did')
// Should retain the old values because Alice is not active. // Should update Alice's tokens because otherwise they'll be stale.
expect(state.accounts[1].handle).toBe('alice.test') expect(state.accounts[1].handle).toBe('alice-updated.test')
expect(state.accounts[1].accessJwt).toBe('alice-access-jwt-1') expect(state.accounts[1].accessJwt).toBe('alice-access-jwt-2')
expect(state.accounts[1].refreshJwt).toBe('alice-refresh-jwt-1') expect(state.accounts[1].refreshJwt).toBe('alice-refresh-jwt-2')
expect(printState(state)).toMatchInlineSnapshot(` expect(printState(state)).toMatchInlineSnapshot(`
{ {
"accounts": [ "accounts": [
@ -948,15 +948,15 @@ describe('session', () => {
"service": "https://bob.com/", "service": "https://bob.com/",
}, },
{ {
"accessJwt": "alice-access-jwt-1", "accessJwt": "alice-access-jwt-2",
"deactivated": false, "deactivated": false,
"did": "alice-did", "did": "alice-did",
"email": undefined, "email": "alice@foo.bar",
"emailAuthFactor": false, "emailAuthFactor": false,
"emailConfirmed": false, "emailConfirmed": false,
"handle": "alice.test", "handle": "alice-updated.test",
"pdsUrl": undefined, "pdsUrl": undefined,
"refreshJwt": "alice-refresh-jwt-1", "refreshJwt": "alice-refresh-jwt-2",
"service": "https://alice.com/", "service": "https://alice.com/",
}, },
], ],
@ -988,7 +988,7 @@ describe('session', () => {
]) ])
expect(state.accounts.length).toBe(2) expect(state.accounts.length).toBe(2)
expect(state.accounts[0].did).toBe('bob-did') expect(state.accounts[0].did).toBe('bob-did')
// Should update the values because Bob is active. // Should update Bob's tokens because otherwise they'll be stale.
expect(state.accounts[0].handle).toBe('bob-updated.test') expect(state.accounts[0].handle).toBe('bob-updated.test')
expect(state.accounts[0].accessJwt).toBe('bob-access-jwt-2') expect(state.accounts[0].accessJwt).toBe('bob-access-jwt-2')
expect(state.accounts[0].refreshJwt).toBe('bob-refresh-jwt-2') expect(state.accounts[0].refreshJwt).toBe('bob-refresh-jwt-2')
@ -1008,15 +1008,15 @@ describe('session', () => {
"service": "https://bob.com/", "service": "https://bob.com/",
}, },
{ {
"accessJwt": "alice-access-jwt-1", "accessJwt": "alice-access-jwt-2",
"deactivated": false, "deactivated": false,
"did": "alice-did", "did": "alice-did",
"email": undefined, "email": "alice@foo.bar",
"emailAuthFactor": false, "emailAuthFactor": false,
"emailConfirmed": false, "emailConfirmed": false,
"handle": "alice.test", "handle": "alice-updated.test",
"pdsUrl": undefined, "pdsUrl": undefined,
"refreshJwt": "alice-refresh-jwt-1", "refreshJwt": "alice-refresh-jwt-2",
"service": "https://alice.com/", "service": "https://alice.com/",
}, },
], ],
@ -1030,7 +1030,7 @@ describe('session', () => {
} }
`) `)
// Ignore other events for inactive agent too. // Ignore other events for inactive agent.
const lastState = state const lastState = state
agent1.session = undefined agent1.session = undefined
state = run(state, [ state = run(state, [

View File

@ -68,8 +68,13 @@ export function reducer(state: State, action: Action): State {
switch (action.type) { switch (action.type) {
case 'received-agent-event': { case 'received-agent-event': {
const {agent, accountDid, refreshedAccount, sessionEvent} = action const {agent, accountDid, refreshedAccount, sessionEvent} = action
if (agent !== state.currentAgentState.agent) { if (
// Only consider events from the active agent. refreshedAccount === undefined &&
agent !== state.currentAgentState.agent
) {
// If the session got cleared out (e.g. due to expiry or network error) but
// this account isn't the active one, don't clear it out at this time.
// This way, if the problem is transient, it'll work on next resume.
return state return state
} }
if (sessionEvent === 'network-error') { if (sessionEvent === 'network-error') {