Page MenuHomePhorge

D15146.1765047700.diff
No OneTemporary

Size
8 KB
Referenced Files
None
Subscribers
None

D15146.1765047700.diff

diff --git a/lib/backup/user-data-restore-context.js b/lib/backup/user-data-restore-context.js
--- a/lib/backup/user-data-restore-context.js
+++ b/lib/backup/user-data-restore-context.js
@@ -19,6 +19,7 @@
import type { QRAuthBackupData } from '../types/tunnelbroker/qr-code-auth-message-types.js';
import { getConfig } from '../utils/config.js';
import { BackupIsNewerError } from '../utils/errors.js';
+import { withAuthMetadataOverride } from '../utils/identity-service.js';
import { useDispatchActionPromise } from '../utils/redux-promise-utils.js';
import { useDispatch, useSelector } from '../utils/redux-utils.js';
@@ -250,19 +251,29 @@
// 6. Update peer device lists
if (startStepIndex <= 5) {
- const updatePeersPromise = (async () => {
- const peerUserIDs = await sqliteAPI.getAuxUserIDs(
- databaseIdentifier.RESTORED,
- );
- const auxUserStoreOperations = await generateAuxUserOpsToUpdatePeers(
- peerUserIDs,
- identityContext.identityClient,
- );
- await sqliteAPI.processDBStoreOperations(
- { auxUserStoreOperations },
- databaseIdentifier.RESTORED,
- );
- })();
+ // we have to use override because AuthMetadata might not yet be
+ // populated to the Identity context component
+ const updatePeersPromise = withAuthMetadataOverride(
+ identityContext,
+ {
+ userID,
+ accessToken,
+ },
+ async () => {
+ const peerUserIDs = await sqliteAPI.getAuxUserIDs(
+ databaseIdentifier.RESTORED,
+ );
+ const auxUserStoreOperations =
+ await generateAuxUserOpsToUpdatePeers(
+ peerUserIDs,
+ identityContext.identityClient,
+ );
+ await sqliteAPI.processDBStoreOperations(
+ { auxUserStoreOperations },
+ databaseIdentifier.RESTORED,
+ );
+ },
+ );
void dispatchActionPromise(
restoreUserDataStepActionTypes,
updatePeersPromise,
diff --git a/lib/shared/identity-client-context.js b/lib/shared/identity-client-context.js
--- a/lib/shared/identity-client-context.js
+++ b/lib/shared/identity-client-context.js
@@ -10,9 +10,19 @@
+accessToken: ?string,
};
+export type PartialAuthMetadata = $Shape<AuthMetadata>;
+
+// TODO: Replace this with mapped type after Flow upgrade
+export type FullAuthMetadata = $ObjMap<
+ AuthMetadata,
+ <T>(prop: T) => $NonMaybeType<T>,
+>;
+
export type IdentityClientContextType = {
+identityClient: IdentityServiceClient,
+getAuthMetadata: () => Promise<AuthMetadata>,
+ +setAuthMetadataOverride: (metadata: PartialAuthMetadata) => void,
+ +clearAuthMetadataOverride: () => void,
};
const IdentityClientContext: React.Context<?IdentityClientContextType> =
diff --git a/lib/utils/identity-service.js b/lib/utils/identity-service.js
--- a/lib/utils/identity-service.js
+++ b/lib/utils/identity-service.js
@@ -4,6 +4,10 @@
import t from 'tcomb';
import identityServiceConfig from '../facts/identity-service.js';
+import type {
+ PartialAuthMetadata,
+ IdentityClientContextType,
+} from '../shared/identity-client-context.js';
import { tShape } from '../utils/validation-utils.js';
export type InboundKeysForDeviceResponse = {
@@ -45,6 +49,27 @@
return `${identityServiceConfig.defaultHttpURL}${path}`;
}
+async function withAuthMetadataOverride<T>(
+ identityClient: IdentityClientContextType,
+ metadataOverride: ?PartialAuthMetadata,
+ closure: () => Promise<T>,
+): Promise<T> {
+ if (!metadataOverride) {
+ return closure();
+ }
+
+ try {
+ identityClient.setAuthMetadataOverride(metadataOverride);
+ return await closure();
+ } finally {
+ identityClient.clearAuthMetadataOverride();
+ }
+}
+
const identityServiceQueryTimeout = 20 * 1000; // twenty seconds
-export { getInboundKeysForDeviceURL, identityServiceQueryTimeout };
+export {
+ getInboundKeysForDeviceURL,
+ identityServiceQueryTimeout,
+ withAuthMetadataOverride,
+};
diff --git a/native/identity-service/identity-service-context-provider.react.js b/native/identity-service/identity-service-context-provider.react.js
--- a/native/identity-service/identity-service-context-provider.react.js
+++ b/native/identity-service/identity-service-context-provider.react.js
@@ -6,7 +6,11 @@
import { getOneTimeKeyValues } from 'lib/shared/crypto-utils.js';
import { createAndSignSingletonDeviceList } from 'lib/shared/device-list-utils.js';
import { IdentityClientContext } from 'lib/shared/identity-client-context.js';
-import type { AuthMetadata } from 'lib/shared/identity-client-context.js';
+import type {
+ AuthMetadata,
+ FullAuthMetadata,
+ PartialAuthMetadata,
+} from 'lib/shared/identity-client-context.js';
import {
type IdentityKeysBlob,
identityKeysBlobValidator,
@@ -71,20 +75,33 @@
}, []);
const accessToken = useSelector(state => state.commServicesAccessToken);
+ const authMetadataOverride = React.useRef<?AuthMetadata>(null);
+
+ const setAuthMetadataOverride = React.useCallback(
+ (metadata: PartialAuthMetadata) => {
+ authMetadataOverride.current = metadata;
+ },
+ [],
+ );
+
+ const clearAuthMetadataOverride = React.useCallback(() => {
+ authMetadataOverride.current = null;
+ }, []);
const getAuthMetadata = React.useCallback<
- () => Promise<{
- +deviceID: string,
- +userID: string,
- +accessToken: string,
- }>,
+ () => Promise<FullAuthMetadata>,
>(async () => {
+ const { userID: userIDOverride, accessToken: csatOverride } =
+ authMetadataOverride.current ?? {};
+
const deviceID = await getContentSigningKey();
- const userID = await userIDPromiseRef.current;
- if (!deviceID || !userID || !accessToken) {
+ const userID = userIDOverride ?? (await userIDPromiseRef.current);
+ const token = csatOverride ?? accessToken;
+
+ if (!deviceID || !userID || !token) {
throw new Error('Identity AuthMetadata is missing');
}
- return { deviceID, userID, accessToken };
+ return { deviceID, userID, accessToken: token };
}, [accessToken]);
const processAuthResult = async (authResult: string, deviceID: string) => {
@@ -842,8 +859,15 @@
() => ({
identityClient: client,
getAuthMetadata,
+ setAuthMetadataOverride,
+ clearAuthMetadataOverride,
}),
- [client, getAuthMetadata],
+ [
+ client,
+ getAuthMetadata,
+ setAuthMetadataOverride,
+ clearAuthMetadataOverride,
+ ],
);
return (
@@ -853,14 +877,8 @@
);
}
-// Unfortunately, Required<AuthMetadata>
-// doesn't work for `prop: ?string`
-type RequiredAuthMetadata = $ObjMap<
- AuthMetadata,
- <T>(prop: T) => $NonMaybeType<T>,
->;
async function rawGetDeviceListsForUsers(
- authMetadata: RequiredAuthMetadata,
+ authMetadata: FullAuthMetadata,
userIDs: $ReadOnlyArray<string>,
): Promise<PeersDeviceLists> {
const {
diff --git a/web/grpc/identity-service-context-provider.react.js b/web/grpc/identity-service-context-provider.react.js
--- a/web/grpc/identity-service-context-provider.react.js
+++ b/web/grpc/identity-service-context-provider.react.js
@@ -7,6 +7,7 @@
import {
IdentityClientContext,
type AuthMetadata,
+ type PartialAuthMetadata,
} from 'lib/shared/identity-client-context.js';
import type {
IdentityServiceClient,
@@ -36,14 +37,29 @@
const userID = useSelector(state => state.currentUserInfo?.id);
const accessToken = useSelector(state => state.commServicesAccessToken);
+ const authMetadataOverride = React.useRef<?AuthMetadata>(null);
+ const setAuthMetadataOverride = React.useCallback(
+ (metadata: PartialAuthMetadata) => {
+ authMetadataOverride.current = metadata;
+ },
+ [],
+ );
+ const clearAuthMetadataOverride = React.useCallback(() => {
+ authMetadataOverride.current = null;
+ }, []);
+
const getAuthMetadata = React.useCallback<
() => Promise<AuthMetadata>,
>(async () => {
const contentSigningKey = await getContentSigningKey();
+
+ const { userID: userIDOverride, accessToken: csatOverride } =
+ authMetadataOverride.current ?? {};
+
return {
- userID,
+ userID: userIDOverride ?? userID,
deviceID: contentSigningKey,
- accessToken,
+ accessToken: csatOverride ?? accessToken,
};
}, [accessToken, userID]);
@@ -171,8 +187,15 @@
() => ({
identityClient: client,
getAuthMetadata,
+ setAuthMetadataOverride,
+ clearAuthMetadataOverride,
}),
- [client, getAuthMetadata],
+ [
+ client,
+ getAuthMetadata,
+ setAuthMetadataOverride,
+ clearAuthMetadataOverride,
+ ],
);
return (

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 6, 7:01 PM (17 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5840285
Default Alt Text
D15146.1765047700.diff (8 KB)

Event Timeline