Page MenuHomePhabricator

D11226.diff
No OneTemporary

D11226.diff

diff --git a/lib/components/keyserver-connection-handler.js b/lib/components/keyserver-connection-handler.js
--- a/lib/components/keyserver-connection-handler.js
+++ b/lib/components/keyserver-connection-handler.js
@@ -11,18 +11,15 @@
} from '../actions/user-actions.js';
import { extractKeyserverIDFromID } from '../keyserver-conn/keyserver-call-utils.js';
import {
- setNewSession,
CANCELLED_ERROR,
type CallKeyserverEndpoint,
} from '../keyserver-conn/keyserver-conn-types.js';
-import { resolveKeyserverSessionInvalidation } from '../keyserver-conn/recovery-utils.js';
+import { useKeyserverRecoveryLogIn } from '../keyserver-conn/recovery-utils.js';
import { filterThreadIDsInFilterList } from '../reducers/calendar-filters-reducer.js';
import {
connectionSelector,
cookieSelector,
deviceTokenSelector,
- urlPrefixSelector,
- sessionIDSelector,
} from '../selectors/keyserver-selectors.js';
import { isLoggedInToKeyserver } from '../selectors/user-selectors.js';
import { useInitialNotificationsEncryptedMessage } from '../shared/crypto-utils.js';
@@ -33,12 +30,11 @@
logInActionSources,
type RecoveryActionSource,
} from '../types/account-types.js';
-import { genericCookieInvalidation } from '../types/session-types.js';
import { authoritativeKeyserverID } from '../utils/authoritative-keyserver.js';
import type { CallSingleKeyserverEndpoint } from '../utils/call-single-keyserver-endpoint.js';
import { getConfig } from '../utils/config.js';
import { useDispatchActionPromise } from '../utils/redux-promise-utils.js';
-import { useSelector, useDispatch } from '../utils/redux-utils.js';
+import { useSelector } from '../utils/redux-utils.js';
import { usingCommServicesAccessToken } from '../utils/services-utils.js';
import sleep from '../utils/sleep.js';
@@ -205,30 +201,6 @@
.activeSessionRecovery,
);
- const preRequestUserInfo = useSelector(state => state.currentUserInfo);
- const sessionID = useSelector(sessionIDSelector(keyserverID));
- const preRequestUserState = React.useMemo(
- () => ({
- currentUserInfo: preRequestUserInfo,
- cookiesAndSessions: {
- [keyserverID]: {
- cookie,
- sessionID,
- },
- },
- }),
- [preRequestUserInfo, keyserverID, cookie, sessionID],
- );
-
- // We only need to do a "spot check" on this value below.
- // - To avoid regenerating performRecovery whenever it changes, we want to
- // make sure it's not in that function's dep list.
- // - If we exclude it from that function's dep list, we'll end up binding in
- // the value of preRequestUserState at the time performRecovery is updated.
- // Instead, by assigning to a ref, we are able to use the latest value.
- const preRequestUserStateRef = React.useRef(preRequestUserState);
- preRequestUserStateRef.current = preRequestUserState;
-
// This async function asks the keyserver for its keys, whereas performAuth
// above gets the keyserver's keys from the identity service
const getInitialNotificationsEncryptedMessageForRecovery =
@@ -266,15 +238,9 @@
],
);
- const dispatch = useDispatch();
- const urlPrefix = useSelector(urlPrefixSelector(keyserverID));
+ const keyserverRecoveryLogIn = useKeyserverRecoveryLogIn(keyserverID);
const performRecovery = React.useCallback(
(recoveryActionSource: RecoveryActionSource) => {
- invariant(
- urlPrefix,
- `urlPrefix for ${keyserverID} should be set during performRecovery`,
- );
-
setAuthInProgress(true);
let cancelled = false;
@@ -285,50 +251,11 @@
const hasBeenCancelled = () => cancelled;
const promise = (async () => {
- const userStateBeforeRecovery = preRequestUserStateRef.current;
try {
- const recoverySessionChange =
- await resolveKeyserverSessionInvalidation(
- dispatch,
- cookie,
- urlPrefix,
- recoveryActionSource,
- keyserverID,
- innerPerformRecovery(recoveryActionSource, hasBeenCancelled),
- );
- const sessionChange =
- recoverySessionChange ?? genericCookieInvalidation;
- if (
- sessionChange.cookieInvalidated ||
- !sessionChange.cookie ||
- !sessionChange.cookie.startsWith('user=')
- ) {
- setNewSession(
- dispatch,
- sessionChange,
- userStateBeforeRecovery,
- null,
- recoveryActionSource,
- keyserverID,
- );
- }
- } catch (e) {
- if (cancelled) {
- return;
- }
-
- console.log(
- `Error while recovering session with keyserver id ${keyserverID}`,
- e,
- );
-
- setNewSession(
- dispatch,
- genericCookieInvalidation,
- userStateBeforeRecovery,
- null,
+ await keyserverRecoveryLogIn(
recoveryActionSource,
- keyserverID,
+ innerPerformRecovery(recoveryActionSource, hasBeenCancelled),
+ hasBeenCancelled,
);
} finally {
if (!cancelled) {
@@ -336,9 +263,10 @@
}
}
})();
+
return [promise, cancel];
},
- [dispatch, cookie, urlPrefix, keyserverID, innerPerformRecovery],
+ [keyserverRecoveryLogIn, innerPerformRecovery],
);
const cancelPendingAuth = React.useRef<?() => void>(null);
diff --git a/lib/keyserver-conn/recovery-utils.js b/lib/keyserver-conn/recovery-utils.js
--- a/lib/keyserver-conn/recovery-utils.js
+++ b/lib/keyserver-conn/recovery-utils.js
@@ -1,13 +1,24 @@
// @flow
+import invariant from 'invariant';
+import * as React from 'react';
+
import {
setNewSession,
type CallKeyserverEndpoint,
} from './keyserver-conn-types.js';
+import {
+ cookieSelector,
+ sessionIDSelector,
+ urlPrefixSelector,
+} from '../selectors/keyserver-selectors.js';
import type { RecoveryActionSource } from '../types/account-types.js';
import type { Endpoint } from '../types/endpoints.js';
import type { Dispatch } from '../types/redux-types.js';
-import type { ClientSessionChange } from '../types/session-types.js';
+import {
+ type ClientSessionChange,
+ genericCookieInvalidation,
+} from '../types/session-types.js';
import callSingleKeyServerEndpoint from '../utils/call-single-keyserver-endpoint.js';
import type {
CallSingleKeyserverEndpoint,
@@ -15,6 +26,7 @@
} from '../utils/call-single-keyserver-endpoint.js';
import { getConfig } from '../utils/config.js';
import { promiseAll } from '../utils/promises.js';
+import { useSelector, useDispatch } from '../utils/redux-utils.js';
import { usingCommServicesAccessToken } from '../utils/services-utils.js';
// This function is a shortcut that tells us whether it's worth even trying to
@@ -115,7 +127,109 @@
return newSessionChange;
}
+function useKeyserverRecoveryLogIn(
+ keyserverID: string,
+): (
+ source: RecoveryActionSource,
+ actionFunc: (
+ callSingleKeyserverEndpoint: CallSingleKeyserverEndpoint,
+ callKeyserverEndpoint: CallKeyserverEndpoint,
+ ) => Promise<mixed>,
+ hasBeenCancelled: () => boolean,
+) => Promise<void> {
+ const preRequestUserInfo = useSelector(state => state.currentUserInfo);
+ const cookie = useSelector(cookieSelector(keyserverID));
+ const sessionID = useSelector(sessionIDSelector(keyserverID));
+ const preRequestUserState = React.useMemo(
+ () => ({
+ currentUserInfo: preRequestUserInfo,
+ cookiesAndSessions: {
+ [keyserverID]: {
+ cookie,
+ sessionID,
+ },
+ },
+ }),
+ [preRequestUserInfo, keyserverID, cookie, sessionID],
+ );
+
+ // We only need to do a "spot check" on this value below.
+ // - To avoid regenerating performRecovery whenever it changes, we want to
+ // make sure it's not in that function's dep list.
+ // - If we exclude it from that function's dep list, we'll end up binding in
+ // the value of preRequestUserState at the time performRecovery is updated.
+ // Instead, by assigning to a ref, we are able to use the latest value.
+ const preRequestUserStateRef = React.useRef(preRequestUserState);
+ preRequestUserStateRef.current = preRequestUserState;
+
+ const dispatch = useDispatch();
+ const urlPrefix = useSelector(urlPrefixSelector(keyserverID));
+
+ return React.useCallback(
+ async (
+ source: RecoveryActionSource,
+ actionFunc: (
+ callSingleKeyserverEndpoint: CallSingleKeyserverEndpoint,
+ callKeyserverEndpoint: CallKeyserverEndpoint,
+ ) => Promise<mixed>,
+ hasBeenCancelled: () => boolean,
+ ) => {
+ invariant(
+ urlPrefix,
+ `urlPrefix for ${keyserverID} should be set during recovery login`,
+ );
+
+ const userStateBeforeRecovery = preRequestUserStateRef.current;
+ try {
+ const recoverySessionChange = await resolveKeyserverSessionInvalidation(
+ dispatch,
+ cookie,
+ urlPrefix,
+ source,
+ keyserverID,
+ actionFunc,
+ );
+ const sessionChange =
+ recoverySessionChange ?? genericCookieInvalidation;
+ if (
+ sessionChange.cookieInvalidated ||
+ !sessionChange.cookie ||
+ !sessionChange.cookie.startsWith('user=')
+ ) {
+ setNewSession(
+ dispatch,
+ sessionChange,
+ userStateBeforeRecovery,
+ null,
+ source,
+ keyserverID,
+ );
+ }
+ } catch (e) {
+ if (hasBeenCancelled()) {
+ return;
+ }
+ console.log(
+ `Error during recovery login with keyserver ${keyserverID}`,
+ e,
+ );
+ setNewSession(
+ dispatch,
+ genericCookieInvalidation,
+ userStateBeforeRecovery,
+ null,
+ source,
+ keyserverID,
+ );
+ throw e;
+ }
+ },
+ [keyserverID, dispatch, cookie, urlPrefix],
+ );
+}
+
export {
canResolveKeyserverSessionInvalidation,
resolveKeyserverSessionInvalidation,
+ useKeyserverRecoveryLogIn,
};

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 25, 10:33 PM (22 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2581169
Default Alt Text
D11226.diff (10 KB)

Event Timeline