diff --git a/lib/actions/user-actions.js b/lib/actions/user-actions.js --- a/lib/actions/user-actions.js +++ b/lib/actions/user-actions.js @@ -52,6 +52,7 @@ } from '../types/subscription-types.js'; import type { MinimallyEncodedRawThreadInfos } from '../types/thread-types'; import type { + CurrentUserInfo, UserInfo, PasswordUpdate, LoggedOutUserInfo, @@ -218,6 +219,11 @@ }; }; +export type KeyserverAuthInput = $ReadOnly<{ + ...KeyserverAuthInfo, + +preRequestUserInfo: ?CurrentUserInfo, +}>; + const keyserverAuthActionTypes = Object.freeze({ started: 'KEYSERVER_AUTH_STARTED', success: 'KEYSERVER_AUTH_SUCCESS', @@ -227,7 +233,7 @@ const keyserverAuth = ( callKeyserverEndpoint: CallKeyserverEndpoint, - ): ((input: KeyserverAuthInfo) => Promise) => + ): ((input: KeyserverAuthInput) => Promise) => async keyserverAuthInfo => { const watchedIDs = threadWatcher.getWatchedIDs(); @@ -236,6 +242,7 @@ calendarQuery, keyserverData, deviceTokenUpdateInput, + preRequestUserInfo, ...restLogInInfo } = keyserverAuthInfo; @@ -325,13 +332,21 @@ logInActionSource: keyserverAuthInfo.logInActionSource, notAcknowledgedPolicies: responses[ashoatKeyserverID].notAcknowledgedPolicies, + preRequestUserInfo, }; }; function useKeyserverAuth(): ( input: KeyserverAuthInfo, ) => Promise { - return useKeyserverCall(keyserverAuth); + const preRequestUserInfo = useSelector(state => state.currentUserInfo); + const callKeyserverAuth = useKeyserverCall(keyserverAuth); + + return React.useCallback( + (input: KeyserverAuthInfo) => + callKeyserverAuth({ preRequestUserInfo, ...input }), + [callKeyserverAuth, preRequestUserInfo], + ); } function mergeUserInfos( diff --git a/lib/reducers/calendar-filters-reducer.test.js b/lib/reducers/calendar-filters-reducer.test.js --- a/lib/reducers/calendar-filters-reducer.test.js +++ b/lib/reducers/calendar-filters-reducer.test.js @@ -179,6 +179,7 @@ const messageInfos: RawMessageInfo[] = []; const payload = { currentUserInfo: { id: '5', username: 'me' }, + preRequestUserInfo: { id: '5', username: 'me' }, threadInfos: {}, messagesResult: { currentAsOf: {}, 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 @@ -1,5 +1,7 @@ // @flow +import invariant from 'invariant'; + import { cookieSelector, sessionIDSelector, @@ -44,7 +46,7 @@ function invalidSessionRecovery( currentReduxState: AppState, - actionCurrentUserInfo: CurrentUserInfo, + actionCurrentUserInfo: ?CurrentUserInfo, logInActionSource: ?LogInActionSource, ): boolean { if ( @@ -54,6 +56,12 @@ ) { return false; } + invariant( + actionCurrentUserInfo, + 'currentUserInfo (preRequestUserInfo) should be defined when ' + + 'COOKIE_INVALIDATION_RESOLUTION_ATTEMPT or ' + + 'SOCKET_AUTH_ERROR_RESOLUTION_ATTEMPT login is dispatched', + ); return ( !currentReduxState.dataLoaded || currentReduxState.currentUserInfo?.id !== actionCurrentUserInfo.id diff --git a/lib/types/account-types.js b/lib/types/account-types.js --- a/lib/types/account-types.js +++ b/lib/types/account-types.js @@ -19,11 +19,12 @@ type RawThreadInfos, type MinimallyEncodedRawThreadInfos, } from './thread-types.js'; -import { - type UserInfo, - type LoggedOutUserInfo, - type LoggedInUserInfo, -} from './user-types.js'; +import type { + CurrentUserInfo, + UserInfo, + LoggedOutUserInfo, + LoggedInUserInfo, +} from './user-types'; import type { PolicyType } from '../facts/policies.js'; import { values } from '../utils/objects.js'; import { tShape } from '../utils/validation-utils.js'; @@ -181,6 +182,7 @@ +updatesCurrentAsOf: { +[keyserverID: string]: number }, +logInActionSource: LogInActionSource, +notAcknowledgedPolicies?: ?$ReadOnlyArray, + +preRequestUserInfo: ?CurrentUserInfo, }; type KeyserverRequestData = { diff --git a/native/redux/redux-setup.js b/native/redux/redux-setup.js --- a/native/redux/redux-setup.js +++ b/native/redux/redux-setup.js @@ -11,6 +11,7 @@ logOutActionTypes, deleteKeyserverAccountActionTypes, logInActionTypes, + keyserverAuthActionTypes, } from 'lib/actions/user-actions.js'; import { setNewSessionActionType } from 'lib/keyserver-conn/keyserver-conn-types.js'; import type { ThreadStoreOperation } from 'lib/ops/thread-store-ops.js'; @@ -148,6 +149,12 @@ state, action.payload.currentUserInfo, action.payload.logInActionSource, + )) || + (action.type === keyserverAuthActionTypes.success && + invalidSessionRecovery( + state, + action.payload.preRequestUserInfo, + action.payload.logInActionSource, )) ) { return state;