diff --git a/lib/types/crypto-types.js b/lib/types/crypto-types.js --- a/lib/types/crypto-types.js +++ b/lib/types/crypto-types.js @@ -26,10 +26,10 @@ }; export type CryptoStore = { - +primaryAccount: ?PickledOLMAccount, - +primaryIdentityKeys: ?OLMIdentityKeys, - +notificationAccount: ?PickledOLMAccount, - +notificationIdentityKeys: ?OLMIdentityKeys, + +primaryAccount: PickledOLMAccount, + +primaryIdentityKeys: OLMIdentityKeys, + +notificationAccount: PickledOLMAccount, + +notificationIdentityKeys: OLMIdentityKeys, }; export type IdentityKeysBlob = { 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 @@ -155,7 +155,7 @@ export type NativeAppState = BaseAppState<>; export type WebAppState = BaseAppState<> & { - +cryptoStore: CryptoStore, + +cryptoStore: ?CryptoStore, +pushApiPublicKey: ?string, ... }; diff --git a/web/account/log-in-form.react.js b/web/account/log-in-form.react.js --- a/web/account/log-in-form.react.js +++ b/web/account/log-in-form.react.js @@ -17,12 +17,7 @@ import OrBreak from '../components/or-break.react.js'; import { initOlm } from '../olm/olm-utils.js'; import { updateNavInfoActionType } from '../redux/action-types.js'; -import { - setPrimaryIdentityKeys, - setNotificationIdentityKeys, - setPickledPrimaryAccount, - setPickledNotificationAccount, -} from '../redux/crypto-store-reducer.js'; +import { setCryptoStore } from '../redux/crypto-store-reducer.js'; import { useSelector } from '../redux/redux-utils.js'; function LoginForm(): React.Node { @@ -30,21 +25,11 @@ const { data: signer } = useWalletClient(); const dispatch = useDispatch(); - const primaryIdentityPublicKeys = useSelector( - state => state.cryptoStore.primaryIdentityKeys, - ); - const notificationIdentityPublicKeys = useSelector( - state => state.cryptoStore.notificationIdentityKeys, - ); + const cryptoStore = useSelector(state => state.cryptoStore); React.useEffect(() => { (async () => { - if ( - primaryIdentityPublicKeys !== null && - primaryIdentityPublicKeys !== undefined && - notificationIdentityPublicKeys !== null && - notificationIdentityPublicKeys !== undefined - ) { + if (cryptoStore !== null && cryptoStore !== undefined) { return; } await initOlm(); @@ -54,24 +39,11 @@ const { ed25519: identityED25519, curve25519: identityCurve25519 } = JSON.parse(identityAccount.identity_keys()); - dispatch({ - type: setPrimaryIdentityKeys, - payload: { ed25519: identityED25519, curve25519: identityCurve25519 }, - }); - const identityAccountPicklingKey = uuid.v4(); const pickledIdentityAccount = identityAccount.pickle( identityAccountPicklingKey, ); - dispatch({ - type: setPickledPrimaryAccount, - payload: { - picklingKey: identityAccountPicklingKey, - pickledAccount: pickledIdentityAccount, - }, - }); - const notificationAccount = new olm.Account(); notificationAccount.create(); const { @@ -79,28 +51,34 @@ curve25519: notificationCurve25519, } = JSON.parse(notificationAccount.identity_keys()); - dispatch({ - type: setNotificationIdentityKeys, - payload: { - ed25519: notificationED25519, - curve25519: notificationCurve25519, - }, - }); - const notificationAccountPicklingKey = uuid.v4(); const pickledNotificationAccount = notificationAccount.pickle( notificationAccountPicklingKey, ); dispatch({ - type: setPickledNotificationAccount, + type: setCryptoStore, payload: { - picklingKey: notificationAccountPicklingKey, - pickledAccount: pickledNotificationAccount, + primaryAccount: { + picklingKey: identityAccountPicklingKey, + pickledAccount: pickledIdentityAccount, + }, + primaryIdentityKeys: { + ed25519: identityED25519, + curve25519: identityCurve25519, + }, + notificationAccount: { + picklingKey: notificationAccountPicklingKey, + pickledAccount: pickledNotificationAccount, + }, + notificationIdentityKeys: { + ed25519: notificationED25519, + curve25519: notificationCurve25519, + }, }, }); })(); - }, [dispatch, notificationIdentityPublicKeys, primaryIdentityPublicKeys]); + }, [dispatch, cryptoStore]); const onQRCodeLoginButtonClick = React.useCallback(() => { dispatch({ diff --git a/web/account/qr-code-login.react.js b/web/account/qr-code-login.react.js --- a/web/account/qr-code-login.react.js +++ b/web/account/qr-code-login.react.js @@ -13,7 +13,7 @@ function QrCodeLogin(): React.Node { const [qrCodeValue, setQrCodeValue] = React.useState(); const ed25519Key = useSelector( - state => state.cryptoStore.primaryIdentityKeys?.ed25519, + state => state.cryptoStore?.primaryIdentityKeys.ed25519, ); const generateQRCode = React.useCallback(async () => { diff --git a/web/account/siwe-login-form.react.js b/web/account/siwe-login-form.react.js --- a/web/account/siwe-login-form.react.js +++ b/web/account/siwe-login-form.react.js @@ -85,7 +85,7 @@ }, [dispatchActionPromise, getSIWENonceCall, siweNonceShouldBeFetched]); const primaryIdentityPublicKeys: ?OLMIdentityKeys = useSelector( - state => state.cryptoStore.primaryIdentityKeys, + state => state.cryptoStore?.primaryIdentityKeys, ); const signedIdentityKeysBlob: ?SignedIdentityKeysBlob = diff --git a/web/redux/crypto-store-reducer.js b/web/redux/crypto-store-reducer.js --- a/web/redux/crypto-store-reducer.js +++ b/web/redux/crypto-store-reducer.js @@ -9,52 +9,20 @@ import type { Action } from './redux-setup.js'; -const setPrimaryIdentityKeys = 'SET_PRIMARY_IDENTITY_KEYS'; -const setNotificationIdentityKeys = 'SET_NOTIFICATION_IDENTITY_KEYS'; -const setPickledPrimaryAccount = 'SET_PICKLED_PRIMARY_ACCOUNT'; -const setPickledNotificationAccount = 'SET_PICKLED_NOTIFICATION_ACCOUNT'; +const setCryptoStore = 'SET_CRYPTO_STORE'; -function reduceCryptoStore(state: CryptoStore, action: Action): CryptoStore { - if (action.type === setPrimaryIdentityKeys) { - return { - ...state, - primaryIdentityKeys: action.payload, - }; - } else if (action.type === setNotificationIdentityKeys) { - return { - ...state, - notificationIdentityKeys: action.payload, - }; - } else if (action.type === setPickledPrimaryAccount) { - return { - ...state, - primaryAccount: action.payload, - }; - } else if (action.type === setPickledNotificationAccount) { - return { - ...state, - notificationAccount: action.payload, - }; +function reduceCryptoStore(state: ?CryptoStore, action: Action): ?CryptoStore { + if (action.type === setCryptoStore) { + return action.payload; } else if ( action.type === logOutActionTypes.success || action.type === deleteAccountActionTypes.success || (action.type === setNewSessionActionType && action.payload.sessionChange.cookieInvalidated) ) { - return { - primaryAccount: null, - primaryIdentityKeys: null, - notificationAccount: null, - notificationIdentityKeys: null, - }; + return null; } return state; } -export { - setPrimaryIdentityKeys, - setNotificationIdentityKeys, - setPickledPrimaryAccount, - setPickledNotificationAccount, - reduceCryptoStore, -}; +export { setCryptoStore, reduceCryptoStore }; diff --git a/web/redux/default-state.js b/web/redux/default-state.js --- a/web/redux/default-state.js +++ b/web/redux/default-state.js @@ -39,12 +39,7 @@ }, windowActive: true, pushApiPublicKey: null, - cryptoStore: { - primaryAccount: null, - primaryIdentityKeys: null, - notificationAccount: null, - notificationIdentityKeys: null, - }, + cryptoStore: null, windowDimensions: { width: window.width, height: window.height }, loadingStatuses: {}, calendarFilters: defaultCalendarFilters, 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 @@ -13,11 +13,7 @@ import { isLoggedIn } from 'lib/selectors/user-selectors.js'; import { invalidSessionDowngrade } from 'lib/shared/session-utils.js'; import type { Shape } from 'lib/types/core.js'; -import type { - CryptoStore, - OLMIdentityKeys, - PickledOLMAccount, -} from 'lib/types/crypto-types.js'; +import type { CryptoStore } from 'lib/types/crypto-types.js'; import type { DraftStore } from 'lib/types/draft-types.js'; import type { EnabledApps } from 'lib/types/enabled-apps.js'; import type { EntryStore, CalendarQuery } from 'lib/types/entry-types.js'; @@ -46,13 +42,7 @@ setInitialReduxState, } from './action-types.js'; import { reduceCommunityPickerStore } from './community-picker-reducer.js'; -import { - reduceCryptoStore, - setPrimaryIdentityKeys, - setNotificationIdentityKeys, - setPickledNotificationAccount, - setPickledPrimaryAccount, -} from './crypto-store-reducer.js'; +import { reduceCryptoStore, setCryptoStore } from './crypto-store-reducer.js'; import reduceNavInfo from './nav-reducer.js'; import { onStateDifference } from './redux-debug-utils.js'; import { getVisibility } from './visibility.js'; @@ -91,7 +81,7 @@ +dataLoaded: boolean, +windowActive: boolean, +userPolicies: UserPolicies, - +cryptoStore: CryptoStore, + +cryptoStore: ?CryptoStore, +pushApiPublicKey: ?string, +_persist: ?PersistState, +commServicesAccessToken: ?string, @@ -114,10 +104,7 @@ type: 'UPDATE_WINDOW_ACTIVE', payload: boolean, } - | { +type: 'SET_PRIMARY_IDENTITY_KEYS', payload: ?OLMIdentityKeys } - | { +type: 'SET_NOTIFICATION_IDENTITY_KEYS', payload: ?OLMIdentityKeys } - | { +type: 'SET_PICKLED_PRIMARY_ACCOUNT', payload: ?PickledOLMAccount } - | { +type: 'SET_PICKLED_NOTIFICATION_ACCOUNT', payload: ?PickledOLMAccount } + | { +type: 'SET_CRYPTO_STORE', payload: CryptoStore } | { +type: 'SET_INITIAL_REDUX_STATE', payload: InitialReduxState }; export function reducer(oldState: AppState | void, action: Action): AppState { @@ -196,10 +183,7 @@ if ( action.type !== updateNavInfoActionType && - action.type !== setPrimaryIdentityKeys && - action.type !== setNotificationIdentityKeys && - action.type !== setPickledPrimaryAccount && - action.type !== setPickledNotificationAccount + action.type !== setCryptoStore ) { const baseReducerResult = baseReducer(state, action, onStateDifference); state = baseReducerResult.state; diff --git a/web/selectors/socket-selectors.js b/web/selectors/socket-selectors.js --- a/web/selectors/socket-selectors.js +++ b/web/selectors/socket-selectors.js @@ -15,10 +15,9 @@ } from 'lib/selectors/socket-selectors.js'; import { createOpenSocketFunction } from 'lib/shared/socket-utils.js'; import type { - OLMIdentityKeys, - PickledOLMAccount, SignedIdentityKeysBlob, IdentityKeysBlob, + CryptoStore, } from 'lib/types/crypto-types.js'; import type { ClientServerRequest, @@ -68,20 +67,16 @@ const getSignedIdentityKeysBlobSelector: ( state: AppState, ) => ?() => Promise = createSelector( - (state: AppState) => state.cryptoStore.primaryAccount, - (state: AppState) => state.cryptoStore.primaryIdentityKeys, - (state: AppState) => state.cryptoStore.notificationIdentityKeys, - ( - primaryAccount: ?PickledOLMAccount, - primaryIdentityKeys: ?OLMIdentityKeys, - notificationIdentityKeys: ?OLMIdentityKeys, - ) => { - if (!primaryAccount || !primaryIdentityKeys || !notificationIdentityKeys) { + (state: AppState) => state.cryptoStore, + (cryptoStore: ?CryptoStore) => { + if (!cryptoStore) { return null; } return async () => { await initOlm(); + const { primaryAccount, primaryIdentityKeys, notificationIdentityKeys } = + cryptoStore; const primaryOLMAccount = new olm.Account(); primaryOLMAccount.unpickle( primaryAccount.picklingKey, diff --git a/web/selectors/tunnelbroker-selectors.js b/web/selectors/tunnelbroker-selectors.js --- a/web/selectors/tunnelbroker-selectors.js +++ b/web/selectors/tunnelbroker-selectors.js @@ -8,7 +8,7 @@ export const createTunnelbrokerInitMessage: AppState => ?ConnectionInitializationMessage = createSelector( - state => state.cryptoStore.primaryIdentityKeys?.ed25519, + state => state.cryptoStore?.primaryIdentityKeys.ed25519, state => state.commServicesAccessToken, state => state.currentUserInfo?.id, (