diff --git a/lib/selectors/account-selectors.js b/lib/selectors/account-selectors.js --- a/lib/selectors/account-selectors.js +++ b/lib/selectors/account-selectors.js @@ -1,5 +1,6 @@ // @flow +import _memoize from 'lodash/memoize.js'; import { createSelector } from 'reselect'; import { @@ -10,8 +11,12 @@ import { currentCalendarQuery } from './nav-selectors.js'; import type { LogInExtraInfo } from '../types/account-types.js'; import type { CalendarQuery } from '../types/entry-types.js'; +import type { KeyserverInfos } from '../types/keyserver-types.js'; import type { AppState } from '../types/redux-types.js'; -import type { PreRequestUserState } from '../types/session-types.js'; +import type { + PreRequestUserState, + PreRequestUserKeyserverSessionInfo, +} from '../types/session-types.js'; import type { CurrentUserInfo } from '../types/user-types.js'; const logInExtraInfoSelector: ( @@ -40,7 +45,10 @@ }, ); -const preRequestUserStateSelector: (state: AppState) => PreRequestUserState = +const basePreRequestUserStateForSingleKeyserverSelector: ( + keyserverID: string, + // eslint-disable-next-line no-unused-vars +) => (state: AppState) => PreRequestUserState = keyserverID => createSelector( (state: AppState) => state.currentUserInfo, cookieSelector, @@ -51,9 +59,39 @@ sessionID: ?string, ) => ({ currentUserInfo, - cookie, - sessionID, + cookiesAndSessions: { [keyserverID]: { cookie, sessionID } }, }), ); -export { logInExtraInfoSelector, preRequestUserStateSelector }; +const preRequestUserStateForSingleKeyserverSelector: ( + keyserverID: string, +) => (state: AppState) => PreRequestUserState = _memoize( + basePreRequestUserStateForSingleKeyserverSelector, +); + +const preRequestUserStateSelector: (state: AppState) => PreRequestUserState = + createSelector( + (state: AppState) => state.currentUserInfo, + (state: AppState) => state.keyserverStore.keyserverInfos, + (currentUserInfo: ?CurrentUserInfo, keyserverInfos: KeyserverInfos) => { + const cookiesAndSessions: { + [string]: PreRequestUserKeyserverSessionInfo, + } = {}; + for (const keyserverID in keyserverInfos) { + cookiesAndSessions[keyserverID] = { + cookie: keyserverInfos[keyserverID].cookie, + sessionID: keyserverInfos[keyserverID].sessionID, + }; + } + return { + currentUserInfo, + cookiesAndSessions, + }; + }, + ); + +export { + logInExtraInfoSelector, + preRequestUserStateForSingleKeyserverSelector, + preRequestUserStateSelector, +}; diff --git a/lib/shared/session-utils.js b/lib/shared/session-utils.js --- a/lib/shared/session-utils.js +++ b/lib/shared/session-utils.js @@ -11,6 +11,7 @@ import type { AppState } from '../types/redux-types.js'; import type { PreRequestUserState } from '../types/session-types.js'; import type { CurrentUserInfo } from '../types/user-types.js'; +import { ashoatKeyserverID } from '../utils/validation-utils.js'; function invalidSessionDowngrade( currentReduxState: AppState, @@ -34,8 +35,10 @@ (actionCurrentUserInfo && actionCurrentUserInfo.anonymous)) && preRequestUserState && (preRequestUserState.currentUserInfo?.id !== currentCurrentUserInfo.id || - preRequestUserState.cookie !== cookieSelector(currentReduxState) || - preRequestUserState.sessionID !== sessionIDSelector(currentReduxState)) + preRequestUserState.cookiesAndSessions[ashoatKeyserverID].cookie !== + cookieSelector(currentReduxState) || + preRequestUserState.cookiesAndSessions[ashoatKeyserverID].sessionID !== + sessionIDSelector(currentReduxState)) ); } diff --git a/lib/types/session-types.js b/lib/types/session-types.js --- a/lib/types/session-types.js +++ b/lib/types/session-types.js @@ -81,12 +81,18 @@ +cookie?: string, }; -export type PreRequestUserState = { - +currentUserInfo: ?CurrentUserInfo, +export type PreRequestUserKeyserverSessionInfo = { +cookie: ?string, +sessionID: ?string, }; +export type PreRequestUserState = { + +currentUserInfo: ?CurrentUserInfo, + +cookiesAndSessions: { + +[keyserverID: string]: PreRequestUserKeyserverSessionInfo, + }, +}; + export type SetSessionPayload = { sessionChange: ClientSessionChange, preRequestUserState: ?PreRequestUserState, diff --git a/lib/utils/action-utils.js b/lib/utils/action-utils.js --- a/lib/utils/action-utils.js +++ b/lib/utils/action-utils.js @@ -303,7 +303,10 @@ setNewSession( dispatch, sessionChange, - { currentUserInfo, cookie, sessionID }, + { + currentUserInfo, + cookiesAndSessions: { [keyserverID]: { cookie, sessionID } }, + }, error, undefined, ); diff --git a/native/socket.react.js b/native/socket.react.js --- a/native/socket.react.js +++ b/native/socket.react.js @@ -5,7 +5,7 @@ import { useDispatch } from 'react-redux'; import { useLogOut, logOutActionTypes } from 'lib/actions/user-actions.js'; -import { preRequestUserStateSelector } from 'lib/selectors/account-selectors.js'; +import { preRequestUserStateForSingleKeyserverSelector } from 'lib/selectors/account-selectors.js'; import { cookieSelector, urlPrefixSelector, @@ -62,7 +62,9 @@ const openSocket = useSelector(openSocketSelector(ashoatKeyserverID)); invariant(openSocket, 'openSocket failed to be created'); const sessionIdentification = useSelector(sessionIdentificationSelector); - const preRequestUserState = useSelector(preRequestUserStateSelector); + const preRequestUserState = useSelector( + preRequestUserStateForSingleKeyserverSelector(ashoatKeyserverID), + ); const getInitialNotificationsEncryptedMessage = useInitialNotificationsEncryptedMessage(); diff --git a/web/socket.react.js b/web/socket.react.js --- a/web/socket.react.js +++ b/web/socket.react.js @@ -5,7 +5,7 @@ import { useDispatch } from 'react-redux'; import { useLogOut } from 'lib/actions/user-actions.js'; -import { preRequestUserStateSelector } from 'lib/selectors/account-selectors.js'; +import { preRequestUserStateForSingleKeyserverSelector } from 'lib/selectors/account-selectors.js'; import { cookieSelector, urlPrefixSelector, @@ -46,7 +46,9 @@ const openSocket = useSelector(openSocketSelector(ashoatKeyserverID)); invariant(openSocket, 'openSocket failed to be created'); const sessionIdentification = useSelector(sessionIdentificationSelector); - const preRequestUserState = useSelector(preRequestUserStateSelector); + const preRequestUserState = useSelector( + preRequestUserStateForSingleKeyserverSelector(ashoatKeyserverID), + ); const getClientResponses = useSelector(webGetClientResponsesSelector); const sessionStateFunc = useSelector( webSessionStateFuncSelector(ashoatKeyserverID),