Page MenuHomePhabricator

D10679.id35815.diff
No OneTemporary

D10679.id35815.diff

diff --git a/lib/keyserver-conn/call-keyserver-endpoint-provider.react.js b/lib/keyserver-conn/call-keyserver-endpoint-provider.react.js
--- a/lib/keyserver-conn/call-keyserver-endpoint-provider.react.js
+++ b/lib/keyserver-conn/call-keyserver-endpoint-provider.react.js
@@ -1,6 +1,8 @@
// @flow
+import invariant from 'invariant';
import _memoize from 'lodash/memoize.js';
+import * as React from 'react';
import { createSelector } from 'reselect';
import { setNewSession } from './keyserver-conn-types.js';
@@ -20,139 +22,25 @@
} from '../utils/call-server-endpoint.js';
import callServerEndpoint from '../utils/call-server-endpoint.js';
+export type ActionFunc<F> = (callServerEndpoint: CallServerEndpoint) => F;
+type CreateBoundServerCallsSelectorType = <F>(
+ ActionFunc<F>,
+) => BindServerCallsParams => F;
+type CallKeyserverEndpointContextType = {
+ +bindCookieAndUtilsIntoCallServerEndpoint: (
+ params: BindServerCallsParams,
+ ) => CallServerEndpoint,
+ +createBoundServerCallsSelector: CreateBoundServerCallsSelectorType,
+};
+
+const CallKeyserverEndpointContext: React.Context<?CallKeyserverEndpointContextType> =
+ React.createContext();
+
let currentlyWaitingForNewCookie = false;
let serverEndpointCallsWaitingForNewCookie: ((
callServerEndpoint: ?CallServerEndpoint,
) => void)[] = [];
-// Third param is optional and gets called with newCookie if we get a new cookie
-// Necessary to propagate cookie in cookieInvalidationRecovery below
-function bindCookieAndUtilsIntoCallServerEndpoint(
- params: BindServerCallsParams,
-): CallServerEndpoint {
- const {
- dispatch,
- cookie,
- urlPrefix,
- sessionID,
- currentUserInfo,
- isSocketConnected,
- lastCommunicatedPlatformDetails,
- keyserverID,
- } = params;
- const loggedIn = !!(currentUserInfo && !currentUserInfo.anonymous && true);
- const boundSetNewSession = (
- sessionChange: ClientSessionChange,
- error: ?string,
- ) =>
- setNewSession(
- dispatch,
- sessionChange,
- {
- currentUserInfo,
- cookiesAndSessions: { [keyserverID]: { cookie, sessionID } },
- },
- error,
- undefined,
- keyserverID,
- );
- const canResolveInvalidation = canResolveKeyserverSessionInvalidation();
- // This function gets called before callServerEndpoint sends a request,
- // to make sure that we're not in the middle of trying to recover
- // an invalidated cookie
- const waitIfCookieInvalidated = () => {
- if (!canResolveInvalidation) {
- // If there is no way to resolve the session invalidation,
- // just let the caller callServerEndpoint instance continue
- return Promise.resolve(null);
- }
- if (!currentlyWaitingForNewCookie) {
- // Our cookie seems to be valid
- return Promise.resolve(null);
- }
- // Wait to run until we get our new cookie
- return new Promise<?CallServerEndpoint>(r =>
- serverEndpointCallsWaitingForNewCookie.push(r),
- );
- };
- // This function is a helper for the next function defined below
- const attemptToResolveInvalidation = async (
- sessionChange: ClientSessionChange,
- ) => {
- const newAnonymousCookie = sessionChange.cookie;
- const newSessionChange = await resolveKeyserverSessionInvalidation(
- dispatch,
- newAnonymousCookie,
- urlPrefix,
- logInActionSources.cookieInvalidationResolutionAttempt,
- keyserverID,
- );
-
- currentlyWaitingForNewCookie = false;
- const currentWaitingCalls = serverEndpointCallsWaitingForNewCookie;
- serverEndpointCallsWaitingForNewCookie = [];
-
- const newCallServerEndpoint = newSessionChange
- ? bindCookieAndUtilsIntoCallServerEndpoint({
- ...params,
- cookie: newSessionChange.cookie,
- sessionID: newSessionChange.sessionID,
- currentUserInfo: newSessionChange.currentUserInfo,
- })
- : null;
- for (const func of currentWaitingCalls) {
- func(newCallServerEndpoint);
- }
- return newCallServerEndpoint;
- };
- // If this function is called, callServerEndpoint got a response invalidating
- // its cookie, and is wondering if it should just like... give up?
- // Or if there's a chance at redemption
- const cookieInvalidationRecovery = (sessionChange: ClientSessionChange) => {
- if (!canResolveInvalidation) {
- // If there is no way to resolve the session invalidation,
- // just let the caller callServerEndpoint instance continue
- return Promise.resolve(null);
- }
- if (!loggedIn) {
- // We don't want to attempt any use native credentials of a logged out
- // user to log-in after a cookieInvalidation while logged out
- return Promise.resolve(null);
- }
- if (currentlyWaitingForNewCookie) {
- return new Promise<?CallServerEndpoint>(r =>
- serverEndpointCallsWaitingForNewCookie.push(r),
- );
- }
- currentlyWaitingForNewCookie = true;
- return attemptToResolveInvalidation(sessionChange);
- };
-
- return (
- endpoint: Endpoint,
- data: Object,
- options?: ?CallServerEndpointOptions,
- ) =>
- callServerEndpoint(
- cookie,
- boundSetNewSession,
- waitIfCookieInvalidated,
- cookieInvalidationRecovery,
- urlPrefix,
- sessionID,
- isSocketConnected,
- lastCommunicatedPlatformDetails,
- socketAPIHandler,
- endpoint,
- data,
- dispatch,
- options,
- loggedIn,
- keyserverID,
- );
-}
-
-export type ActionFunc<F> = (callServerEndpoint: CallServerEndpoint) => F;
export type BindServerCallsParams = {
+dispatch: Dispatch,
+cookie: ?string,
@@ -164,56 +52,213 @@
+keyserverID: string,
};
-// 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
-// propagating the cookie (and any future config info that callServerEndpoint
-// needs) through to the server calls so they can pass it to callServerEndpoint.
-// Instead, we "curry" the cookie onto callServerEndpoint within react-redux's
-// connect's mapStateToProps function, and then pass that "bound"
-// callServerEndpoint that no longer needs the cookie as a parameter on to
-// the server call.
-const baseCreateBoundServerCallsSelector = <F>(
- actionFunc: ActionFunc<F>,
-): (BindServerCallsParams => F) =>
- createSelector(
- (state: BindServerCallsParams) => state.dispatch,
- (state: BindServerCallsParams) => state.cookie,
- (state: BindServerCallsParams) => state.urlPrefix,
- (state: BindServerCallsParams) => state.sessionID,
- (state: BindServerCallsParams) => state.currentUserInfo,
- (state: BindServerCallsParams) => state.isSocketConnected,
- (state: BindServerCallsParams) => state.lastCommunicatedPlatformDetails,
- (state: BindServerCallsParams) => state.keyserverID,
- (
- dispatch: Dispatch,
- cookie: ?string,
- urlPrefix: string,
- sessionID: ?string,
- currentUserInfo: ?CurrentUserInfo,
- isSocketConnected: boolean,
- lastCommunicatedPlatformDetails: ?PlatformDetails,
- keyserverID: string,
+type Props = {
+ +children: React.Node,
+};
+function CallKeyserverEndpointProvider(props: Props): React.Node {
+ const bindCookieAndUtilsIntoCallServerEndpoint: (
+ params: BindServerCallsParams,
+ ) => CallServerEndpoint = React.useCallback(params => {
+ const {
+ dispatch,
+ cookie,
+ urlPrefix,
+ sessionID,
+ currentUserInfo,
+ isSocketConnected,
+ lastCommunicatedPlatformDetails,
+ keyserverID,
+ } = params;
+ const loggedIn = !!(currentUserInfo && !currentUserInfo.anonymous && true);
+ const boundSetNewSession = (
+ sessionChange: ClientSessionChange,
+ error: ?string,
+ ) =>
+ setNewSession(
+ dispatch,
+ sessionChange,
+ {
+ currentUserInfo,
+ cookiesAndSessions: { [keyserverID]: { cookie, sessionID } },
+ },
+ error,
+ undefined,
+ keyserverID,
+ );
+ const canResolveInvalidation = canResolveKeyserverSessionInvalidation();
+ // This function gets called before callServerEndpoint sends a request,
+ // to make sure that we're not in the middle of trying to recover
+ // an invalidated cookie
+ const waitIfCookieInvalidated = () => {
+ if (!canResolveInvalidation) {
+ // If there is no way to resolve the session invalidation,
+ // just let the caller callServerEndpoint instance continue
+ return Promise.resolve(null);
+ }
+ if (!currentlyWaitingForNewCookie) {
+ // Our cookie seems to be valid
+ return Promise.resolve(null);
+ }
+ // Wait to run until we get our new cookie
+ return new Promise<?CallServerEndpoint>(r =>
+ serverEndpointCallsWaitingForNewCookie.push(r),
+ );
+ };
+ // This function is a helper for the next function defined below
+ const attemptToResolveInvalidation = async (
+ sessionChange: ClientSessionChange,
) => {
- const boundCallServerEndpoint = bindCookieAndUtilsIntoCallServerEndpoint({
+ const newAnonymousCookie = sessionChange.cookie;
+ const newSessionChange = await resolveKeyserverSessionInvalidation(
dispatch,
+ newAnonymousCookie,
+ urlPrefix,
+ logInActionSources.cookieInvalidationResolutionAttempt,
+ keyserverID,
+ );
+
+ currentlyWaitingForNewCookie = false;
+ const currentWaitingCalls = serverEndpointCallsWaitingForNewCookie;
+ serverEndpointCallsWaitingForNewCookie = [];
+
+ const newCallServerEndpoint = newSessionChange
+ ? bindCookieAndUtilsIntoCallServerEndpoint({
+ ...params,
+ cookie: newSessionChange.cookie,
+ sessionID: newSessionChange.sessionID,
+ currentUserInfo: newSessionChange.currentUserInfo,
+ })
+ : null;
+ for (const func of currentWaitingCalls) {
+ func(newCallServerEndpoint);
+ }
+ return newCallServerEndpoint;
+ };
+ // If this function is called, callServerEndpoint got a response
+ // invalidating its cookie, and is wondering if it should just like...
+ // give up? Or if there's a chance at redemption
+ const cookieInvalidationRecovery = (sessionChange: ClientSessionChange) => {
+ if (!canResolveInvalidation) {
+ // If there is no way to resolve the session invalidation,
+ // just let the caller callServerEndpoint instance continue
+ return Promise.resolve(null);
+ }
+ if (!loggedIn) {
+ // We don't want to attempt any use native credentials of a logged out
+ // user to log-in after a cookieInvalidation while logged out
+ return Promise.resolve(null);
+ }
+ if (currentlyWaitingForNewCookie) {
+ return new Promise<?CallServerEndpoint>(r =>
+ serverEndpointCallsWaitingForNewCookie.push(r),
+ );
+ }
+ currentlyWaitingForNewCookie = true;
+ return attemptToResolveInvalidation(sessionChange);
+ };
+
+ return (
+ endpoint: Endpoint,
+ data: Object,
+ options?: ?CallServerEndpointOptions,
+ ) =>
+ callServerEndpoint(
cookie,
+ boundSetNewSession,
+ waitIfCookieInvalidated,
+ cookieInvalidationRecovery,
urlPrefix,
sessionID,
- currentUserInfo,
isSocketConnected,
lastCommunicatedPlatformDetails,
+ socketAPIHandler,
+ endpoint,
+ data,
+ dispatch,
+ options,
+ loggedIn,
keyserverID,
- });
- return actionFunc(boundCallServerEndpoint);
- },
+ );
+ }, []);
+
+ // 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
+ // propagating the cookie (and any future config info that callServerEndpoint
+ // needs) through to the server calls so they can pass it to
+ // callServerEndpoint. Instead, we "curry" the cookie onto callServerEndpoint
+ // within react-redux's connect's mapStateToProps function, and then pass that
+ // "bound" callServerEndpoint that no longer needs the cookie as a parameter
+ // on to the server call.
+ const baseCreateBoundServerCallsSelector = React.useCallback(
+ <F>(actionFunc: ActionFunc<F>): (BindServerCallsParams => F) =>
+ createSelector(
+ (state: BindServerCallsParams) => state.dispatch,
+ (state: BindServerCallsParams) => state.cookie,
+ (state: BindServerCallsParams) => state.urlPrefix,
+ (state: BindServerCallsParams) => state.sessionID,
+ (state: BindServerCallsParams) => state.currentUserInfo,
+ (state: BindServerCallsParams) => state.isSocketConnected,
+ (state: BindServerCallsParams) => state.lastCommunicatedPlatformDetails,
+ (state: BindServerCallsParams) => state.keyserverID,
+ (
+ dispatch: Dispatch,
+ cookie: ?string,
+ urlPrefix: string,
+ sessionID: ?string,
+ currentUserInfo: ?CurrentUserInfo,
+ isSocketConnected: boolean,
+ lastCommunicatedPlatformDetails: ?PlatformDetails,
+ keyserverID: string,
+ ) => {
+ const boundCallServerEndpoint =
+ bindCookieAndUtilsIntoCallServerEndpoint({
+ dispatch,
+ cookie,
+ urlPrefix,
+ sessionID,
+ currentUserInfo,
+ isSocketConnected,
+ lastCommunicatedPlatformDetails,
+ keyserverID,
+ });
+ return actionFunc(boundCallServerEndpoint);
+ },
+ ),
+ [bindCookieAndUtilsIntoCallServerEndpoint],
);
-type CreateBoundServerCallsSelectorType = <F>(
- ActionFunc<F>,
-) => BindServerCallsParams => F;
-const createBoundServerCallsSelector: CreateBoundServerCallsSelectorType =
- (_memoize(baseCreateBoundServerCallsSelector): any);
+ const createBoundServerCallsSelector: CreateBoundServerCallsSelectorType =
+ React.useMemo(
+ () => _memoize(baseCreateBoundServerCallsSelector),
+ [baseCreateBoundServerCallsSelector],
+ );
+
+ const value = React.useMemo(
+ () => ({
+ bindCookieAndUtilsIntoCallServerEndpoint,
+ createBoundServerCallsSelector,
+ }),
+ [bindCookieAndUtilsIntoCallServerEndpoint, createBoundServerCallsSelector],
+ );
+
+ return (
+ <CallKeyserverEndpointContext.Provider value={value}>
+ {props.children}
+ </CallKeyserverEndpointContext.Provider>
+ );
+}
+
+function useCallKeyserverEndpointContext(): CallKeyserverEndpointContextType {
+ const callKeyserverEndpointContext = React.useContext(
+ CallKeyserverEndpointContext,
+ );
+ invariant(
+ callKeyserverEndpointContext,
+ 'callKeyserverEndpointContext should be set',
+ );
+ return callKeyserverEndpointContext;
+}
let socketAPIHandler: ?SocketAPIHandler = null;
function registerActiveSocket(passedSocketAPIHandler: ?SocketAPIHandler) {
@@ -221,7 +266,7 @@
}
export {
- createBoundServerCallsSelector,
+ CallKeyserverEndpointProvider,
+ useCallKeyserverEndpointContext,
registerActiveSocket,
- bindCookieAndUtilsIntoCallServerEndpoint,
};
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
@@ -8,7 +8,7 @@
import {
type ActionFunc,
type BindServerCallsParams,
- createBoundServerCallsSelector,
+ useCallKeyserverEndpointContext,
} from '../keyserver-conn/call-keyserver-endpoint-provider.react.js';
import { serverCallStateSelector } from '../selectors/server-calls.js';
@@ -20,6 +20,7 @@
const serverCallState = useSelector(
serverCallStateSelector(ashoatKeyserverID),
);
+ const { createBoundServerCallsSelector } = useCallKeyserverEndpointContext();
return React.useMemo(() => {
const { urlPrefix, isSocketConnected } = serverCallState;
invariant(
@@ -37,7 +38,13 @@
...paramOverride,
keyserverID: ashoatKeyserverID,
});
- }, [serverCall, serverCallState, dispatch, paramOverride]);
+ }, [
+ serverCall,
+ serverCallState,
+ dispatch,
+ paramOverride,
+ createBoundServerCallsSelector,
+ ]);
}
export { useServerCall };
diff --git a/lib/utils/keyserver-call.js b/lib/utils/keyserver-call.js
--- a/lib/utils/keyserver-call.js
+++ b/lib/utils/keyserver-call.js
@@ -12,7 +12,7 @@
import { useSelector, useDispatch } from './redux-utils.js';
import { useDerivedObject } from '../hooks/objects.js';
import {
- bindCookieAndUtilsIntoCallServerEndpoint,
+ useCallKeyserverEndpointContext,
type BindServerCallsParams,
} from '../keyserver-conn/call-keyserver-endpoint-provider.react.js';
import type { PlatformDetails } from '../types/device-types.js';
@@ -39,6 +39,9 @@
// The first argument of the memoized function is used as the map cache key.
const baseCreateBoundServerCallsSelector = (
keyserverID: string,
+ bindCookieAndUtilsIntoCallServerEndpoint: (
+ params: BindServerCallsParams,
+ ) => CallServerEndpoint,
): (BindServerCallsParams => CallServerEndpoint) =>
createSelector(
(state: BindServerCallsParams) => state.dispatch,
@@ -71,6 +74,9 @@
type CreateBoundServerCallsSelectorType = (
keyserverID: string,
+ bindCookieAndUtilsIntoCallServerEndpoint: (
+ params: BindServerCallsParams,
+ ) => CallServerEndpoint,
) => BindServerCallsParams => CallServerEndpoint;
const createBoundServerCallsSelector: CreateBoundServerCallsSelectorType =
_memoize(baseCreateBoundServerCallsSelector);
@@ -130,6 +136,8 @@
currentUserInfo: ?CurrentUserInfo,
keyserverCallInfos: { +[keyserverID: string]: KeyserverCallInfo },
): BindCallKeyserverSelector {
+ const { bindCookieAndUtilsIntoCallServerEndpoint } =
+ useCallKeyserverEndpointContext();
return React.useMemo(
() =>
_memoize(
@@ -152,6 +160,7 @@
const boundCallServerEndpoint = createBoundServerCallsSelector(
keyserverID,
+ bindCookieAndUtilsIntoCallServerEndpoint,
)({
dispatch,
currentUserInfo,
@@ -180,7 +189,12 @@
return keyserverCall(callKeyserverEndpoint, keyserverIDs);
},
),
- [dispatch, currentUserInfo, keyserverCallInfos],
+ [
+ dispatch,
+ currentUserInfo,
+ keyserverCallInfos,
+ bindCookieAndUtilsIntoCallServerEndpoint,
+ ],
);
}
diff --git a/native/root.react.js b/native/root.react.js
--- a/native/root.react.js
+++ b/native/root.react.js
@@ -29,6 +29,7 @@
import IntegrityHandler from 'lib/components/integrity-handler.react.js';
import KeyserverConnectionsHandler from 'lib/components/keyserver-connections-handler.js';
import { MediaCacheProvider } from 'lib/components/media-cache-provider.react.js';
+import { CallKeyserverEndpointProvider } from 'lib/keyserver-conn/call-keyserver-endpoint-provider.react.js';
import { TunnelbrokerProvider } from 'lib/tunnelbroker/tunnelbroker-context.js';
import { actionLogger } from 'lib/utils/action-logger.js';
@@ -296,64 +297,66 @@
}
return (
<GestureHandlerRootView style={styles.app}>
- <StaffContextProvider>
- <IdentityServiceContextProvider>
- <TunnelbrokerProvider
- initMessage={tunnelbrokerInitMessage}
- peerToPeerMessageHandler={peerToPeerMessageHandler}
- >
- <FeatureFlagsProvider>
- <NavContext.Provider value={navContext}>
- <RootContext.Provider value={rootContext}>
- <InputStateContainer>
- <MessageEditingContextProvider>
- <SafeAreaProvider initialMetrics={initialWindowMetrics}>
- <ActionSheetProvider>
- <ENSCacheProvider provider={provider}>
- <MediaCacheProvider
- persistence={filesystemMediaCache}
- >
- <EditUserAvatarProvider>
- <NativeEditThreadAvatarProvider>
- <MarkdownContextProvider>
- <MessageSearchProvider>
- <BottomSheetProvider>
- <RegistrationContextProvider>
- <SQLiteDataHandler />
- <ConnectedStatusBar />
- <ReduxPersistGate
- persistor={getPersistor()}
- >
- {gated}
- </ReduxPersistGate>
- <PersistedStateGate>
- <KeyserverConnectionsHandler
- socketComponent={Socket}
- detectUnsupervisedBackgroundRef={
- detectUnsupervisedBackgroundRef
- }
- />
- <VersionSupportedChecker />
- </PersistedStateGate>
- {navigation}
- </RegistrationContextProvider>
- </BottomSheetProvider>
- </MessageSearchProvider>
- </MarkdownContextProvider>
- </NativeEditThreadAvatarProvider>
- </EditUserAvatarProvider>
- </MediaCacheProvider>
- </ENSCacheProvider>
- </ActionSheetProvider>
- </SafeAreaProvider>
- </MessageEditingContextProvider>
- </InputStateContainer>
- </RootContext.Provider>
- </NavContext.Provider>
- </FeatureFlagsProvider>
- </TunnelbrokerProvider>
- </IdentityServiceContextProvider>
- </StaffContextProvider>
+ <CallKeyserverEndpointProvider>
+ <StaffContextProvider>
+ <IdentityServiceContextProvider>
+ <TunnelbrokerProvider
+ initMessage={tunnelbrokerInitMessage}
+ peerToPeerMessageHandler={peerToPeerMessageHandler}
+ >
+ <FeatureFlagsProvider>
+ <NavContext.Provider value={navContext}>
+ <RootContext.Provider value={rootContext}>
+ <InputStateContainer>
+ <MessageEditingContextProvider>
+ <SafeAreaProvider initialMetrics={initialWindowMetrics}>
+ <ActionSheetProvider>
+ <ENSCacheProvider provider={provider}>
+ <MediaCacheProvider
+ persistence={filesystemMediaCache}
+ >
+ <EditUserAvatarProvider>
+ <NativeEditThreadAvatarProvider>
+ <MarkdownContextProvider>
+ <MessageSearchProvider>
+ <BottomSheetProvider>
+ <RegistrationContextProvider>
+ <SQLiteDataHandler />
+ <ConnectedStatusBar />
+ <ReduxPersistGate
+ persistor={getPersistor()}
+ >
+ {gated}
+ </ReduxPersistGate>
+ <PersistedStateGate>
+ <KeyserverConnectionsHandler
+ socketComponent={Socket}
+ detectUnsupervisedBackgroundRef={
+ detectUnsupervisedBackgroundRef
+ }
+ />
+ <VersionSupportedChecker />
+ </PersistedStateGate>
+ {navigation}
+ </RegistrationContextProvider>
+ </BottomSheetProvider>
+ </MessageSearchProvider>
+ </MarkdownContextProvider>
+ </NativeEditThreadAvatarProvider>
+ </EditUserAvatarProvider>
+ </MediaCacheProvider>
+ </ENSCacheProvider>
+ </ActionSheetProvider>
+ </SafeAreaProvider>
+ </MessageEditingContextProvider>
+ </InputStateContainer>
+ </RootContext.Provider>
+ </NavContext.Provider>
+ </FeatureFlagsProvider>
+ </TunnelbrokerProvider>
+ </IdentityServiceContextProvider>
+ </StaffContextProvider>
+ </CallKeyserverEndpointProvider>
</GestureHandlerRootView>
);
}
diff --git a/web/root.js b/web/root.js
--- a/web/root.js
+++ b/web/root.js
@@ -11,6 +11,7 @@
import IntegrityHandler from 'lib/components/integrity-handler.react.js';
import KeyserverConnectionsHandler from 'lib/components/keyserver-connections-handler.js';
+import { CallKeyserverEndpointProvider } from 'lib/keyserver-conn/call-keyserver-endpoint-provider.react.js';
import { reduxLoggerMiddleware } from 'lib/utils/action-logger.js';
import {
@@ -42,20 +43,22 @@
const RootProvider = (): React.Node => (
<Provider store={store}>
<ErrorBoundary>
- <InitialReduxStateGate persistor={persistor}>
- <GetOrCreateCryptoStoreProvider>
- <IdentityServiceContextProvider>
- <WebNotificationsSessionCreatorProvider>
- <Router history={history.getHistoryObject()}>
- <Route path="*" component={App} />
- </Router>
- <KeyserverConnectionsHandler socketComponent={Socket} />
- <SQLiteDataHandler />
- <IntegrityHandler />
- </WebNotificationsSessionCreatorProvider>
- </IdentityServiceContextProvider>
- </GetOrCreateCryptoStoreProvider>
- </InitialReduxStateGate>
+ <CallKeyserverEndpointProvider>
+ <InitialReduxStateGate persistor={persistor}>
+ <GetOrCreateCryptoStoreProvider>
+ <IdentityServiceContextProvider>
+ <WebNotificationsSessionCreatorProvider>
+ <Router history={history.getHistoryObject()}>
+ <Route path="*" component={App} />
+ </Router>
+ <KeyserverConnectionsHandler socketComponent={Socket} />
+ <SQLiteDataHandler />
+ <IntegrityHandler />
+ </WebNotificationsSessionCreatorProvider>
+ </IdentityServiceContextProvider>
+ </GetOrCreateCryptoStoreProvider>
+ </InitialReduxStateGate>
+ </CallKeyserverEndpointProvider>
</ErrorBoundary>
</Provider>
);

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 29, 12:36 AM (20 h, 36 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2595212
Default Alt Text
D10679.id35815.diff (27 KB)

Event Timeline