From 52c5d80a896e568fca9c05721977b4798ac72af4 Mon Sep 17 00:00:00 2001 From: Jack Reed <phillipjreed@gmail.com> Date: Wed, 15 Apr 2020 13:38:27 -0600 Subject: [PATCH] Wipeaway the infoResponses for a given token that is reset --- __tests__/src/reducers/infoResponse.test.js | 27 +++++++++++++++++++++ src/state/actions/infoResponse.js | 21 +++++++++------- src/state/reducers/infoResponses.js | 9 +++++++ 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/__tests__/src/reducers/infoResponse.test.js b/__tests__/src/reducers/infoResponse.test.js index c67ceb531..c340e7259 100644 --- a/__tests__/src/reducers/infoResponse.test.js +++ b/__tests__/src/reducers/infoResponse.test.js @@ -28,6 +28,7 @@ describe('info response reducer', () => { content: 'lots of canvases and metadata and such', id: 'abc123', }, + tokenServiceId: 'efg456', type: ActionTypes.RECEIVE_INFO_RESPONSE, }, )).toMatchObject({ @@ -35,6 +36,7 @@ describe('info response reducer', () => { id: 'abc123', isFetching: false, json: {}, + tokenServiceId: 'efg456', }, }); }); @@ -49,6 +51,7 @@ describe('info response reducer', () => { { error: "This institution didn't enable CORS.", infoId: 'abc123', + tokenServiceId: 'efg456', type: ActionTypes.RECEIVE_INFO_RESPONSE_FAILURE, }, )).toEqual({ @@ -56,6 +59,7 @@ describe('info response reducer', () => { error: "This institution didn't enable CORS.", id: 'abc123', isFetching: false, + tokenServiceId: 'efg456', }, }); }); @@ -88,4 +92,27 @@ describe('info response reducer', () => { type: ActionTypes.IMPORT_MIRADOR_STATE, })).toEqual({}); }); + it('should handle RESET_AUTHENTICATION_STATE', () => { + expect(infoResponsesReducer( + { + abc123: { + stuff: 'foo', + tokenServiceId: 'abc123', + }, + def456: { + stuff: 'foo', + tokenServiceId: 'def456', + }, + }, + { + tokenServiceId: 'abc123', + type: ActionTypes.RESET_AUTHENTICATION_STATE, + }, + )).toEqual({ + def456: { + stuff: 'foo', + tokenServiceId: 'def456', + }, + }); + }); }); diff --git a/src/state/actions/infoResponse.js b/src/state/actions/infoResponse.js index a0a869bdd..19a77edc3 100644 --- a/src/state/actions/infoResponse.js +++ b/src/state/actions/infoResponse.js @@ -22,11 +22,12 @@ export function requestInfoResponse(infoId) { * @param {Object} manifestJson * @memberof ActionCreators */ -export function receiveInfoResponse(infoId, infoJson, ok) { +export function receiveInfoResponse(infoId, infoJson, ok, tokenServiceId) { return { infoId, infoJson, ok, + tokenServiceId, type: ActionTypes.RECEIVE_INFO_RESPONSE, }; } @@ -38,15 +39,16 @@ export function receiveInfoResponse(infoId, infoJson, ok) { * @param {String} error * @memberof ActionCreators */ -export function receiveInfoResponseFailure(infoId, error) { +export function receiveInfoResponseFailure(infoId, error, tokenServiceId) { return { error, infoId, + tokenServiceId, type: ActionTypes.RECEIVE_INFO_RESPONSE_FAILURE, }; } /** @private */ -function getAccessToken({ accessTokens }, iiifService) { +function getAccessTokenService({ accessTokens }, iiifService) { if (!iiifService) return undefined; const services = Utils.getServices(iiifService).filter(s => s.getProfile().match(/http:\/\/iiif.io\/api\/auth\/1\//)); @@ -55,7 +57,7 @@ function getAccessToken({ accessTokens }, iiifService) { const authService = services[i]; const accessTokenService = Utils.getService(authService, 'http://iiif.io/api/auth/1/token'); const token = accessTokens[accessTokenService.id]; - if (token && token.json) return token.json.accessToken; + if (token && token.json) return token; } return undefined; @@ -79,21 +81,22 @@ export function fetchInfoResponse({ imageId, imageResource }) { && !state.infoResponses[infoId].isFetching && state.infoResponses[infoId].json; - const token = getAccessToken( + const tokenService = getAccessTokenService( getState(), infoResponse || (imageResource && imageResource.getServices()[0]), ); - if (token) { - headers.Authorization = `Bearer ${token}`; + if (tokenService) { + headers.Authorization = `Bearer ${tokenService.json.accessToken}`; } dispatch(requestInfoResponse(infoId)); + const tokenServiceId = tokenService && tokenService.id; return fetch(`${infoId.replace(/\/$/, '')}/info.json`, { headers }) .then(response => response.json().then(json => ({ json, ok: response.ok }))) - .then(({ json, ok }) => dispatch(receiveInfoResponse(infoId, json, ok))) - .catch(error => dispatch(receiveInfoResponseFailure(infoId, error))); + .then(({ json, ok }) => dispatch(receiveInfoResponse(infoId, json, ok, tokenServiceId))) + .catch(error => dispatch(receiveInfoResponseFailure(infoId, error, tokenServiceId))); }); } diff --git a/src/state/reducers/infoResponses.js b/src/state/reducers/infoResponses.js index 558a2dd12..a20657db0 100644 --- a/src/state/reducers/infoResponses.js +++ b/src/state/reducers/infoResponses.js @@ -22,6 +22,7 @@ export const infoResponsesReducer = (state = {}, action) => { id: action.infoId, isFetching: false, json: action.infoJson, + tokenServiceId: action.tokenServiceId, }, }; case ActionTypes.RECEIVE_INFO_RESPONSE_FAILURE: @@ -31,6 +32,7 @@ export const infoResponsesReducer = (state = {}, action) => { error: action.error, id: action.infoId, isFetching: false, + tokenServiceId: action.tokenServiceId, }, }; case ActionTypes.REMOVE_INFO_RESPONSE: @@ -42,6 +44,13 @@ export const infoResponsesReducer = (state = {}, action) => { }, {}); case ActionTypes.IMPORT_MIRADOR_STATE: return {}; + case ActionTypes.RESET_AUTHENTICATION_STATE: + return Object.keys(state).reduce((object, key) => { + if (state[key].tokenServiceId !== action.tokenServiceId) { + object[key] = state[key]; // eslint-disable-line no-param-reassign + } + return object; + }, {}); default: return state; } }; -- GitLab