diff --git a/keyserver/src/responders/website-responders.js b/keyserver/src/responders/website-responders.js --- a/keyserver/src/responders/website-responders.js +++ b/keyserver/src/responders/website-responders.js @@ -28,6 +28,7 @@ import { defaultWebEnabledApps } from 'lib/types/enabled-apps.js'; import { entryStoreValidator } from 'lib/types/entry-types.js'; import { defaultCalendarFilters } from 'lib/types/filter-types.js'; +import { keyserverStoreValidator } from 'lib/types/keyserver-types.js'; import { inviteLinksStoreValidator } from 'lib/types/link-types.js'; import { defaultNumberPerThread, @@ -253,6 +254,7 @@ 'default lastCommunicatedPlatformDetails', _isEqual({}), ), + keyserverStore: keyserverStoreValidator, }); async function websiteResponder( @@ -600,6 +602,7 @@ commServicesAccessToken: null, inviteLinksStore: inviteLinksStorePromise, lastCommunicatedPlatformDetails: {}, + keyserverStore: { keyserverInfos: {} }, }); const validatedInitialReduxState = validateOutput( viewer.platformDetails, diff --git a/lib/reducers/keyserver-reducer.js b/lib/reducers/keyserver-reducer.js new file mode 100644 --- /dev/null +++ b/lib/reducers/keyserver-reducer.js @@ -0,0 +1,49 @@ +// @flow + +import { resetUserStateActionType } from '../actions/user-actions.js'; +import type { KeyserverStore } from '../types/keyserver-types'; +import type { BaseAction } from '../types/redux-types.js'; +import { setNewSessionActionType } from '../utils/action-utils.js'; +import { ashoatKeyserverID } from '../utils/validation-utils.js'; + +export default function reduceKeyserverStore( + state: KeyserverStore, + action: BaseAction, +): KeyserverStore { + // this action is only dispatched on native + if (action.type === resetUserStateActionType) { + const stateCookie = state.keyserverInfos[ashoatKeyserverID]?.cookie; + const cookie = + stateCookie && stateCookie.startsWith('anonymous=') ? stateCookie : null; + + const keyserverInfos = { ...state.keyserverInfos }; + for (const key in keyserverInfos) { + keyserverInfos[key] = { ...keyserverInfos[key], cookie: null }; + } + + return { + ...state, + keyserverInfos: { + ...keyserverInfos, + [ashoatKeyserverID]: { + ...state.keyserverInfos[ashoatKeyserverID], + cookie, + }, + }, + }; + } else if (action.type === setNewSessionActionType) { + if (action.payload.sessionChange.cookie !== undefined) { + return { + ...state, + keyserverInfos: { + ...state.keyserverInfos, + [ashoatKeyserverID]: { + ...state.keyserverInfos[ashoatKeyserverID], + cookie: action.payload.sessionChange.cookie, + }, + }, + }; + } + } + return state; +} 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 @@ -8,6 +8,7 @@ import reduceEnabledApps from './enabled-apps-reducer.js'; import { reduceEntryInfos } from './entry-reducer.js'; import reduceInviteLinks from './invite-links-reducer.js'; +import reduceKeyserverStore from './keyserver-reducer.js'; import reduceLastCommunicatedPlatformDetails from './last-communicated-platform-details-reducer.js'; import reduceLifecycleState from './lifecycle-state-reducer.js'; import { reduceLoadingStatuses } from './loading-reducer.js'; @@ -133,6 +134,7 @@ action, state.urlPrefix, ), + keyserverStore: reduceKeyserverStore(state.keyserverStore, action), }, storeOperations: { draftStoreOperations, diff --git a/lib/types/keyserver-types.js b/lib/types/keyserver-types.js new file mode 100644 --- /dev/null +++ b/lib/types/keyserver-types.js @@ -0,0 +1,26 @@ +// @flow + +import t, { type TInterface } from 'tcomb'; + +import { tShape } from '../utils/validation-utils.js'; + +// Once we start using the cookie field on web, +// the cookie field type should be changed to string | null. +// See https://linear.app/comm/issue/ENG-4347/stop-using-browser-cookies +export type KeyserverInfo = { + +cookie?: ?string, +}; + +export type KeyserverStore = { + +keyserverInfos: { +[key: string]: KeyserverInfo }, +}; + +export const keyserverInfoValidator: TInterface = + tShape({ + cookie: t.maybe(t.String), + }); + +export const keyserverStoreValidator: TInterface = + tShape({ + keyserverInfos: t.dict(t.String, keyserverInfoValidator), + }); diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js --- a/lib/types/redux-types.js +++ b/lib/types/redux-types.js @@ -39,6 +39,7 @@ CalendarThreadFilter, SetCalendarDeletedFilterPayload, } from './filter-types.js'; +import type { KeyserverStore } from './keyserver-types.js'; import type { LifecycleState } from './lifecycle-state-types.js'; import type { FetchInviteLinksResponse, @@ -138,6 +139,7 @@ +commServicesAccessToken: ?string, +inviteLinksStore: InviteLinksStore, +lastCommunicatedPlatformDetails: LastCommunicatedPlatformDetails, + +keyserverStore: KeyserverStore, ... }; diff --git a/lib/utils/sanitization.js b/lib/utils/sanitization.js --- a/lib/utils/sanitization.js +++ b/lib/utils/sanitization.js @@ -301,7 +301,12 @@ ): AppState { if (state.cookie !== undefined && state.cookie !== null) { const oldState: NativeAppState = state; - state = { ...oldState, cookie: null }; + const keyserverInfos = { ...oldState.keyserverStore.keyserverInfos }; + for (const key in keyserverInfos) { + keyserverInfos[key] = { ...keyserverInfos[key], cookie: null }; + } + const keyserverStore = { ...oldState.keyserverStore, keyserverInfos }; + state = { ...oldState, cookie: null, keyserverStore }; } if (state.deviceToken !== undefined && state.deviceToken !== null) { const oldState: AppState = state; 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 @@ -123,6 +123,7 @@ links: {}, }, lastCommunicatedPlatformDetails: {}, + keyserverStore: { keyserverInfos: {} }, }: AppState); function reducer(state: AppState = defaultState, action: Action) { diff --git a/native/redux/state-types.js b/native/redux/state-types.js --- a/native/redux/state-types.js +++ b/native/redux/state-types.js @@ -8,6 +8,7 @@ import type { EnabledApps } from 'lib/types/enabled-apps.js'; import type { EntryStore } from 'lib/types/entry-types.js'; import type { CalendarFilter } from 'lib/types/filter-types.js'; +import type { KeyserverStore } from 'lib/types/keyserver-types.js'; import type { LifecycleState } from 'lib/types/lifecycle-state-types.js'; import type { InviteLinksStore } from 'lib/types/link-types.js'; import type { LoadingStatus } from 'lib/types/loading-types.js'; @@ -61,4 +62,5 @@ +commServicesAccessToken: ?string, +inviteLinksStore: InviteLinksStore, +lastCommunicatedPlatformDetails: LastCommunicatedPlatformDetails, + +keyserverStore: KeyserverStore, }; diff --git a/native/redux/unshim-utils.js b/native/redux/unshim-utils.js --- a/native/redux/unshim-utils.js +++ b/native/redux/unshim-utils.js @@ -54,7 +54,16 @@ commCoreModule.processMessageStoreOperationsSync(operations); } catch (exception) { console.log(exception); - return { ...state, cookie: null }; + const keyserverInfos = { ...state.keyserverStore.keyserverInfos }; + for (const key in keyserverInfos) { + keyserverInfos[key] = { ...keyserverInfos[key], cookie: null }; + } + const keyserverStore = { ...state.keyserverStore, keyserverInfos }; + return { + ...state, + cookie: null, + keyserverStore, + }; } return state; diff --git a/web/redux/redux-setup.js b/web/redux/redux-setup.js --- a/web/redux/redux-setup.js +++ b/web/redux/redux-setup.js @@ -23,6 +23,7 @@ import type { EnabledApps } from 'lib/types/enabled-apps.js'; import type { EntryStore } from 'lib/types/entry-types.js'; import { type CalendarFilter } from 'lib/types/filter-types.js'; +import type { KeyserverStore } from 'lib/types/keyserver-types.js'; import type { LifecycleState } from 'lib/types/lifecycle-state-types.js'; import type { InviteLinksStore } from 'lib/types/link-types.js'; import type { LoadingStatus } from 'lib/types/loading-types.js'; @@ -100,6 +101,7 @@ +commServicesAccessToken: ?string, +inviteLinksStore: InviteLinksStore, +lastCommunicatedPlatformDetails: LastCommunicatedPlatformDetails, + +keyserverStore: KeyserverStore, }; export type Action =