diff --git a/keyserver/src/creators/account-creator.js b/keyserver/src/creators/account-creator.js --- a/keyserver/src/creators/account-creator.js +++ b/keyserver/src/creators/account-creator.js @@ -178,8 +178,10 @@ return { id, + isNewAccount: true, rawMessageInfos, currentUserInfo, + serverTime: Date.now(), cookieChange: { threadInfos: threadsResult.threadInfos, userInfos: values(userInfos), 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 @@ -85,11 +85,42 @@ registerCallServerEndpointOptions, ); return { + isNewAccount: response.isNewAccount, currentUserInfo: response.currentUserInfo, rawMessageInfos: response.rawMessageInfos, threadInfos: response.cookieChange.threadInfos, userInfos: response.cookieChange.userInfos, calendarQuery: registerInfo.calendarQuery, + updatesCurrentAsOf: response.serverTime, + }; +}; + +const siweActionTypes = Object.freeze({ + started: 'SIWE_STARTED', + success: 'SIWE_SUCCESS', + failed: 'SIWE_FAILED', +}); +const siwe = ( + callServerEndpoint: CallServerEndpoint, +): ((siweInfo: SIWEServerCall) => Promise) => async siweInfo => { + const watchedIDs = threadWatcher.getWatchedIDs(); + const response = await callServerEndpoint( + 'siwe', + { + ...siweInfo, + watchedIDs, + platformDetails: getConfig().platformDetails, + }, + registerCallServerEndpointOptions, + ); + return { + isNewAccount: response.isNewAccount, + currentUserInfo: response.currentUserInfo, + rawMessageInfos: response.rawMessageInfos, + threadInfos: response.cookieChange.threadInfos, + userInfos: response.cookieChange.userInfos, + calendarQuery: siweInfo.calendarQuery, + updatesCurrentAsOf: response.serverTime, }; }; @@ -163,9 +194,9 @@ threadInfos: response.cookieChange.threadInfos, currentUserInfo: response.currentUserInfo, calendarResult: { - calendarQuery: logInInfo.calendarQuery, rawEntryInfos: response.rawEntryInfos, }, + calendarQuery: logInInfo.calendarQuery, messagesResult: { messageInfos: response.rawMessageInfos, truncationStatus: response.truncationStatuses, diff --git a/lib/reducers/calendar-filters-reducer.js b/lib/reducers/calendar-filters-reducer.js --- a/lib/reducers/calendar-filters-reducer.js +++ b/lib/reducers/calendar-filters-reducer.js @@ -9,8 +9,6 @@ import { logOutActionTypes, deleteAccountActionTypes, - logInActionTypes, - registerActionTypes, } from '../actions/user-actions'; import { filteredThreadIDs, @@ -37,7 +35,10 @@ type ClientUpdateInfo, processUpdatesActionType, } from '../types/update-types'; -import { setNewSessionActionType } from '../utils/action-utils'; +import { + setNewSessionActionType, + isSuccessfulAuthType, +} from '../utils/action-utils'; export default function reduceCalendarFilters( state: $ReadOnlyArray, @@ -46,8 +47,7 @@ if ( action.type === logOutActionTypes.success || action.type === deleteAccountActionTypes.success || - action.type === logInActionTypes.success || - action.type === registerActionTypes.success || + isSuccessfulAuthType(action) || (action.type === setNewSessionActionType && action.payload.sessionChange.cookieInvalidated) ) { diff --git a/lib/reducers/connection-reducer.js b/lib/reducers/connection-reducer.js --- a/lib/reducers/connection-reducer.js +++ b/lib/reducers/connection-reducer.js @@ -1,5 +1,4 @@ // @flow - import { updateActivityActionTypes } from '../actions/activity-actions'; import { updateCalendarQueryActionTypes } from '../actions/entry-actions'; import { @@ -7,6 +6,7 @@ deleteAccountActionTypes, logInActionTypes, registerActionTypes, + siweActionTypes, } from '../actions/user-actions'; import { queueActivityUpdatesActionType } from '../types/activity-types'; import { defaultCalendarQuery } from '../types/entry-types'; @@ -76,8 +76,10 @@ } else if (action.type === logInActionTypes.success) { return { ...state, - actualizedCalendarQuery: action.payload.calendarResult.calendarQuery, + actualizedCalendarQuery: action.payload.calendarQuery, }; + } else if (action.type === siweActionTypes.success) { + return { ...state, actualizedCalendarQuery: action.payload.calendarQuery }; } else if ( action.type === registerActionTypes.success || action.type === updateCalendarQueryActionTypes.success || diff --git a/lib/reducers/data-loaded-reducer.js b/lib/reducers/data-loaded-reducer.js --- a/lib/reducers/data-loaded-reducer.js +++ b/lib/reducers/data-loaded-reducer.js @@ -1,24 +1,19 @@ // @flow - import { logOutActionTypes, deleteAccountActionTypes, - logInActionTypes, - registerActionTypes, - siweActionTypes, } from '../actions/user-actions'; import type { BaseAction } from '../types/redux-types'; -import { setNewSessionActionType } from '../utils/action-utils'; +import { + setNewSessionActionType, + isSuccessfulAuthType, +} from '../utils/action-utils'; export default function reduceDataLoaded( state: boolean, action: BaseAction, ): boolean { - if ( - action.type === logInActionTypes.success || - action.type === registerActionTypes.success || - action.type === siweActionTypes.success - ) { + if (isSuccessfulAuthType(action)) { return true; } else if ( action.type === setNewSessionActionType && diff --git a/lib/reducers/entry-reducer.js b/lib/reducers/entry-reducer.js --- a/lib/reducers/entry-reducer.js +++ b/lib/reducers/entry-reducer.js @@ -1,5 +1,4 @@ // @flow - import invariant from 'invariant'; import _filter from 'lodash/fp/filter'; import _flow from 'lodash/fp/flow'; @@ -37,6 +36,7 @@ logOutActionTypes, deleteAccountActionTypes, logInActionTypes, + siweActionTypes, } from '../actions/user-actions'; import { entryID, @@ -487,7 +487,10 @@ }, [], ]; - } else if (action.type === logInActionTypes.success) { + } else if ( + action.type === logInActionTypes.success || + (action.type === siweActionTypes.success && !action.payload.isNewAccount) + ) { const { calendarResult } = action.payload; if (calendarResult) { const [updatedEntryInfos, updatedDaysToEntries] = mergeNewEntryInfos( diff --git a/lib/reducers/master-reducer.js b/lib/reducers/master-reducer.js --- a/lib/reducers/master-reducer.js +++ b/lib/reducers/master-reducer.js @@ -1,6 +1,4 @@ // @flow - -import { registerActionTypes, logInActionTypes } from '../actions/user-actions'; import type { BaseNavInfo } from '../types/nav-types'; import type { BaseAppState, BaseAction } from '../types/redux-types'; import { @@ -8,6 +6,7 @@ incrementalStateSyncActionType, } from '../types/socket-types'; import type { StoreOperations } from '../types/store-ops-types'; +import { isSuccessfulAuthType } from '../utils/action-utils'; import reduceCalendarFilters from './calendar-filters-reducer'; import reduceConnectionInfo from './connection-reducer'; import reduceDataLoaded from './data-loaded-reducer'; @@ -61,8 +60,7 @@ connection.status !== 'connected' && action.type !== incrementalStateSyncActionType && action.type !== fullStateSyncActionType && - action.type !== registerActionTypes.success && - action.type !== logInActionTypes.success + !isSuccessfulAuthType(action) ) { if (messageStore.currentAsOf !== state.messageStore.currentAsOf) { messageStore = { diff --git a/lib/reducers/message-reducer.js b/lib/reducers/message-reducer.js --- a/lib/reducers/message-reducer.js +++ b/lib/reducers/message-reducer.js @@ -1,5 +1,4 @@ // @flow - import invariant from 'invariant'; import _difference from 'lodash/fp/difference'; import _flow from 'lodash/fp/flow'; @@ -48,6 +47,7 @@ deleteAccountActionTypes, logInActionTypes, registerActionTypes, + siweActionTypes, } from '../actions/user-actions'; import { pendingToRealizedThreadIDsSelector } from '../selectors/thread-selectors'; import { @@ -689,7 +689,11 @@ action: BaseAction, newThreadInfos: { +[id: string]: RawThreadInfo }, ): ReduceMessageStoreResult { - if (action.type === logInActionTypes.success) { + if ( + action.type === logInActionTypes.success || + (action.type === siweActionTypes.success && !action.payload.isNewAccount) + ) { + // $FlowFixMe const messagesResult = action.payload.messagesResult; const { messageStoreOperations, @@ -845,6 +849,23 @@ truncationStatuses, newThreadInfos, ); + } else if ( + action.type === siweActionTypes.success && + action.payload.isNewAccount + ) { + const truncationStatuses = {}; + // $FlowFixMe + for (const messageInfo of action.payload.rawMessageInfos) { + truncationStatuses[messageInfo.threadID] = + messageTruncationStatus.EXHAUSTIVE; + } + return mergeNewMessages( + messageStore, + // $FlowFixMe + action.payload.rawMessageInfos, + truncationStatuses, + newThreadInfos, + ); } else if ( action.type === changeThreadSettingsActionTypes.success || action.type === removeUsersFromThreadActionTypes.success || diff --git a/lib/reducers/thread-reducer.js b/lib/reducers/thread-reducer.js --- a/lib/reducers/thread-reducer.js +++ b/lib/reducers/thread-reducer.js @@ -20,8 +20,6 @@ import { logOutActionTypes, deleteAccountActionTypes, - logInActionTypes, - registerActionTypes, updateSubscriptionActionTypes, } from '../actions/user-actions'; import type { BaseAction } from '../types/redux-types'; @@ -48,7 +46,10 @@ processUpdatesActionType, } from '../types/update-types'; import { actionLogger } from '../utils/action-logger'; -import { setNewSessionActionType } from '../utils/action-utils'; +import { + setNewSessionActionType, + isSuccessfulAuthType, +} from '../utils/action-utils'; import { getConfig } from '../utils/config'; import { sanitizeActionSecrets } from '../utils/sanitization'; @@ -156,11 +157,8 @@ newThreadInconsistencies: $ReadOnlyArray, threadStoreOperations: $ReadOnlyArray, } { - if ( - action.type === logInActionTypes.success || - action.type === registerActionTypes.success || - action.type === fullStateSyncActionType - ) { + if (isSuccessfulAuthType(action) || action.type === fullStateSyncActionType) { + // $FlowFixMe const newThreadInfos = action.payload.threadInfos; const threadStoreOperations = [ { diff --git a/lib/reducers/updates-reducer.js b/lib/reducers/updates-reducer.js --- a/lib/reducers/updates-reducer.js +++ b/lib/reducers/updates-reducer.js @@ -1,6 +1,5 @@ // @flow - -import { logInActionTypes } from '../actions/user-actions'; +import { logInActionTypes, siweActionTypes } from '../actions/user-actions'; import type { BaseAction } from '../types/redux-types'; import { fullStateSyncActionType, @@ -12,7 +11,10 @@ currentAsOf: number, action: BaseAction, ): number { - if (action.type === logInActionTypes.success) { + if ( + action.type === logInActionTypes.success || + action.type === siweActionTypes.success + ) { return action.payload.updatesCurrentAsOf; } else if (action.type === fullStateSyncActionType) { return action.payload.updatesCurrentAsOf; 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 @@ -55,12 +55,14 @@ export type RegisterResponse = { id: string, + isNewAccount: boolean, rawMessageInfos: $ReadOnlyArray, currentUserInfo: OldLoggedInUserInfo | LoggedInUserInfo, cookieChange: { threadInfos: { +[id: string]: RawThreadInfo }, userInfos: $ReadOnlyArray, }, + serverTime: number, }; export type RegisterResult = { @@ -69,6 +71,9 @@ +threadInfos: { +[id: string]: RawThreadInfo }, +userInfos: $ReadOnlyArray, +calendarQuery: CalendarQuery, + +isNewAccount: boolean, + +calendarResult?: ?CalendarResult, + +updatesCurrentAsOf: number, }; export type DeleteAccountRequest = { @@ -137,8 +142,10 @@ +messagesResult: GenericMessagesResult, +userInfos: $ReadOnlyArray, +calendarResult: CalendarResult, + +calendarQuery: CalendarQuery, +updatesCurrentAsOf: number, +logInActionSource: LogInActionSource, + +isNewAccount?: boolean, }; export type SIWERequest = { diff --git a/lib/types/entry-types.js b/lib/types/entry-types.js --- a/lib/types/entry-types.js +++ b/lib/types/entry-types.js @@ -196,7 +196,6 @@ export type CalendarResult = { +rawEntryInfos: $ReadOnlyArray, - +calendarQuery: CalendarQuery, }; export type CalendarQueryUpdateStartingPayload = { 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 @@ -5,6 +5,11 @@ import { useSelector, useDispatch } from 'react-redux'; import { createSelector } from 'reselect'; +import { + logInActionTypes, + registerActionTypes, + siweActionTypes, +} from '../actions/user-actions'; import { serverCallStateSelector } from '../selectors/server-calls'; import { logInActionSources, @@ -366,6 +371,29 @@ connectionStatus: ConnectionStatus, }; +function isSuccessfulAuthType(action: BaseAction): boolean { + const isAuthType: boolean = + action.type === logInActionTypes.success || + action.type === registerActionTypes.success || + action.type === siweActionTypes.success; + return isAuthType; +} + +function isSuccessfulLogin(action: BaseAction): boolean { + if ( + action.type !== logInActionTypes.success || + action.type !== siweActionTypes.success + ) { + return false; + } + let isNewAccount = false; + if (action.type === siweActionTypes.success) { + isNewAccount = action.payload.isNewAccount; + } + const isLogin: boolean = action.type === logInActionTypes.success; + return isLogin || !isNewAccount; +} + // All server calls needs to include some information from the Redux state // (namely, the cookie). This information is used deep in the server call, // at the point where callServerEndpoint is called. We don't want to bother @@ -437,4 +465,6 @@ createBoundServerCallsSelector, registerActiveSocket, useServerCall, + isSuccessfulAuthType, + isSuccessfulLogin, };