diff --git a/lib/shared/identity-client-context.js b/lib/shared/identity-client-context.js index 49bdab848..da710a44d 100644 --- a/lib/shared/identity-client-context.js +++ b/lib/shared/identity-client-context.js @@ -1,14 +1,14 @@ // @flow import * as React from 'react'; import type { IdentityServiceClient } from '../types/identity-service-types.js'; export type IdentityClientContextType = { - +identityClient: ?IdentityServiceClient, + +identityClient: IdentityServiceClient, }; const IdentityClientContext: React.Context = React.createContext(); export { IdentityClientContext }; diff --git a/native/identity-service/identity-service-context-provider.react.js b/native/identity-service/identity-service-context-provider.react.js index 2eff6650d..419853887 100644 --- a/native/identity-service/identity-service-context-provider.react.js +++ b/native/identity-service/identity-service-context-provider.react.js @@ -1,137 +1,138 @@ // @flow import * as React from 'react'; import { getOneTimeKeyArray } from 'lib/shared/crypto-utils.js'; import { IdentityClientContext } from 'lib/shared/identity-client-context.js'; import type { IdentityServiceClient, OutboundKeyInfoResponse, UserLoginResponse, } from 'lib/types/identity-service-types.js'; import { ONE_TIME_KEYS_NUMBER } from 'lib/types/identity-service-types.js'; import { getCommServicesAuthMetadataEmitter } from '../event-emitters/csa-auth-metadata-emitter.js'; import { commCoreModule, commRustModule } from '../native-modules.js'; import { getContentSigningKey } from '../utils/crypto-utils.js'; type Props = { +children: React.Node, }; function IdentityServiceContextProvider(props: Props): React.Node { const { children } = props; const authMetadataPromiseRef = React.useRef>(); if (!authMetadataPromiseRef.current) { authMetadataPromiseRef.current = (async () => { const { userID, accessToken } = await commCoreModule.getCommServicesAuthMetadata(); return { userID, accessToken }; })(); } React.useEffect(() => { const metadataEmitter = getCommServicesAuthMetadataEmitter(); const subscription = metadataEmitter.addListener( 'commServicesAuthMetadata', (authMetadata: UserLoginResponse) => { authMetadataPromiseRef.current = Promise.resolve({ userID: authMetadata.userId, accessToken: authMetadata.accessToken, }); }, ); return () => subscription.remove(); }, []); const getAuthMetadata = React.useCallback< () => Promise<{ +deviceID: string, +userID: string, +accessToken: string, }>, >(async () => { const deviceID = await getContentSigningKey(); const authMetadata = await authMetadataPromiseRef.current; const userID = authMetadata?.userID; const accessToken = authMetadata?.accessToken; if (!deviceID || !userID || !accessToken) { throw new Error('Identity service client is not initialized'); } return { deviceID, userID, accessToken }; }, []); - const client = React.useMemo(() => { - return { + const client = React.useMemo( + () => ({ deleteUser: async () => { const { deviceID, userID, accessToken } = await getAuthMetadata(); return commRustModule.deleteUser(userID, deviceID, accessToken); }, getKeyserverKeys: async (keyserverID: string) => { const { deviceID, userID, accessToken } = await getAuthMetadata(); const result = await commRustModule.getKeyserverKeys( userID, deviceID, accessToken, keyserverID, ); const resultObject: OutboundKeyInfoResponse = JSON.parse(result); if ( !resultObject.payload || !resultObject.payloadSignature || !resultObject.contentPrekey || !resultObject.contentPrekeySignature || !resultObject.notifPrekey || !resultObject.notifPrekeySignature ) { throw new Error('Invalid response from Identity service'); } return resultObject; }, registerUser: async (username: string, password: string) => { await commCoreModule.initializeCryptoAccount(); const [ { blobPayload, signature }, notificationsOneTimeKeys, primaryOneTimeKeys, prekeys, ] = await Promise.all([ commCoreModule.getUserPublicKey(), commCoreModule.getNotificationsOneTimeKeys(ONE_TIME_KEYS_NUMBER), commCoreModule.getPrimaryOneTimeKeys(ONE_TIME_KEYS_NUMBER), commCoreModule.generateAndGetPrekeys(), ]); const registrationResult = await commRustModule.registerUser( username, password, blobPayload, signature, prekeys.contentPrekey, prekeys.contentPrekeySignature, prekeys.notifPrekey, prekeys.notifPrekeySignature, getOneTimeKeyArray(primaryOneTimeKeys), getOneTimeKeyArray(notificationsOneTimeKeys), ); const { userID, accessToken } = JSON.parse(registrationResult); return { accessToken, userID, username }; }, - }; - }, [getAuthMetadata]); + }), + [getAuthMetadata], + ); const value = React.useMemo( () => ({ identityClient: client, }), [client], ); return ( {children} ); } export default IdentityServiceContextProvider; diff --git a/web/grpc/identity-service-context-provider.react.js b/web/grpc/identity-service-context-provider.react.js index 3db503c7e..ba3c95e58 100644 --- a/web/grpc/identity-service-context-provider.react.js +++ b/web/grpc/identity-service-context-provider.react.js @@ -1,50 +1,48 @@ // @flow import * as React from 'react'; import { IdentityClientContext } from 'lib/shared/identity-client-context.js'; -import type { IdentityServiceClient } from 'lib/types/identity-service-types.js'; import { IdentityServiceClientWrapper } from './identity-service-client-wrapper.js'; import { useSelector } from '../redux/redux-utils.js'; type Props = { +children: React.Node, }; function IdentityServiceContextProvider(props: Props): React.Node { const { children } = props; - const [client, setClient] = React.useState(); const userID = useSelector(state => state.currentUserInfo?.id); const accessToken = useSelector(state => state.commServicesAccessToken); const deviceID = useSelector( state => state.cryptoStore?.primaryIdentityKeys.ed25519, ); - React.useEffect(() => { + const client = React.useMemo(() => { let authLayer = null; if (userID && deviceID && accessToken) { authLayer = { userID, deviceID, commServicesAccessToken: accessToken, }; } - setClient(new IdentityServiceClientWrapper(authLayer)); + return new IdentityServiceClientWrapper(authLayer); }, [accessToken, deviceID, userID]); const value = React.useMemo( () => ({ identityClient: client, }), [client], ); return ( {children} ); } export default IdentityServiceContextProvider;