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 @@ -84,23 +84,35 @@ ); } +// actionCurrentUserInfo can either be the CurrentUserInfo at the time the +// recovery began (preRequestUserInfo), or the CurrentUserInfo in the action. +// We expect that for a recovery they should be the same. The intention is to +// make sure that the CurrentUserInfo in Redux at the time this action is +// processed is the same as the user from whom the recovery was attempted. If +// that user has since logged out, we should ignore the result of the recovery. +const actionSourcesCheckedForInvalidSessionRecovery = new Set([ + recoveryActionSources.cookieInvalidationResolutionAttempt, + recoveryActionSources.socketAuthErrorResolutionAttempt, + recoveryActionSources.appStartCookieLoggedInButInvalidRedux, + recoveryActionSources.appStartReduxLoggedInButInvalidCookie, + recoveryActionSources.refetchUserDataAfterAcknowledgment, + recoveryActionSources.socketNotLoggedIn, +]); function invalidSessionRecovery( currentReduxState: AppState, actionCurrentUserInfo: ?CurrentUserInfo, authActionSource: ?AuthActionSource, ): boolean { if ( - authActionSource !== - recoveryActionSources.cookieInvalidationResolutionAttempt && - authActionSource !== recoveryActionSources.socketAuthErrorResolutionAttempt + !authActionSource || + !actionSourcesCheckedForInvalidSessionRecovery.has(authActionSource) ) { return false; } invariant( actionCurrentUserInfo, - 'currentUserInfo (preRequestUserInfo) should be defined when ' + - 'COOKIE_INVALIDATION_RESOLUTION_ATTEMPT or ' + - 'SOCKET_AUTH_ERROR_RESOLUTION_ATTEMPT login is dispatched', + 'actionCurrentUserInfo should be passed to invalidSessionRecovery for ' + + `${authActionSource} login`, ); if (actionCurrentUserInfo.anonymous) { // It's not a session recovery if the CurrentUserInfo is anonymous