Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F32164250
D15146.1765047700.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D15146.1765047700.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D15146: [lib][native][web] Add a way to override Identity AuthMetadata
Attached
Detach File
Event Timeline
Log In to Comment