diff --git a/native/components/identity-handler.react.js b/native/components/identity-handler.react.js new file mode 100644 --- /dev/null +++ b/native/components/identity-handler.react.js @@ -0,0 +1,123 @@ +// @flow + +import * as React from 'react'; + +import { setAccessTokenActionType } from 'lib/actions/user-actions.js'; +import { isLoggedIn } from 'lib/selectors/user-selectors.js'; +import { getOneTimeKeyArray } from 'lib/shared/crypto-utils.js'; +import { useDispatch } from 'lib/utils/redux-utils.js'; +import { isValidEthereumAddress } from 'lib/utils/siwe-utils.js'; + +import { fetchNativeCredentials } from '../account/native-credentials.js'; +import { commCoreModule, commRustModule } from '../native-modules.js'; +import { useSelector } from '../redux/redux-utils.js'; + +const ONE_TIME_KEYS_NUMBER = 10; + +function IdentityHandler(): React.Node { + const loggedIn = useSelector(isLoggedIn); + const dispatch = useDispatch(); + + React.useEffect(() => { + void (async () => { + if (loggedIn) { + await commCoreModule.initializeCryptoAccount(); + const authMetadata = await commCoreModule.getCommServicesAuthMetadata(); + console.log(authMetadata); + if (authMetadata.accessToken) { + console.log('CSAT present'); + return; + } + + const credentials = await fetchNativeCredentials(); + if (!credentials) { + return; + } + const { username, password } = credentials; + if (!username || isValidEthereumAddress(username)) { + return; + } + + const [ + { + notificationIdentityPublicKeys, + primaryIdentityPublicKeys, + signature, + }, + notificationsOneTimeKeys, + primaryOneTimeKeys, + prekeys, + ] = await Promise.all([ + commCoreModule.getUserPublicKey(), + commCoreModule.getNotificationsOneTimeKeys(ONE_TIME_KEYS_NUMBER), + commCoreModule.getPrimaryOneTimeKeys(ONE_TIME_KEYS_NUMBER), + commCoreModule.generateAndGetPrekeys(), + ]); + + const keyPayload = JSON.stringify({ + notificationIdentityPublicKeys, + primaryIdentityPublicKeys, + }); + + let authResult: ?string = null; + + try { + authResult = await commRustModule.registerUser( + username, + password, + keyPayload, + signature, + prekeys.contentPrekey, + prekeys.contentPrekeySignature, + prekeys.notifPrekey, + prekeys.notifPrekeySignature, + getOneTimeKeyArray(primaryOneTimeKeys), + getOneTimeKeyArray(notificationsOneTimeKeys), + ); + console.log('Registered to identity'); + } catch (registerError) { + console.log( + 'User PROBABLY already exists, trying to log in: ', + registerError, + ); + try { + authResult = await commRustModule.loginPasswordUser( + username, + password, + keyPayload, + signature, + prekeys.contentPrekey, + prekeys.contentPrekeySignature, + prekeys.notifPrekey, + prekeys.notifPrekeySignature, + getOneTimeKeyArray(primaryOneTimeKeys), + getOneTimeKeyArray(notificationsOneTimeKeys), + ); + console.log('Logged in to identity'); + } catch (loginError) { + console.log('Login error ', loginError); + } + } + + if (!authResult) { + return; + } + const { userID, accessToken } = JSON.parse(authResult); + await commCoreModule.setCommServicesAuthMetadata( + userID, + primaryIdentityPublicKeys.ed25519, + accessToken, + ); + dispatch({ type: setAccessTokenActionType, payload: accessToken }); + console.log('CSAT set, now Tunnelbroker should be connected'); + } else { + await commCoreModule.clearCommServicesAccessToken(); + console.log('clearing CSAT'); + } + })(); + }, [dispatch, loggedIn]); + + return null; +} + +export default IdentityHandler; diff --git a/native/root.react.js b/native/root.react.js --- a/native/root.react.js +++ b/native/root.react.js @@ -39,6 +39,7 @@ import ChatContextProvider from './chat/chat-context-provider.react.js'; import MessageEditingContextProvider from './chat/message-editing-context-provider.react.js'; import { FeatureFlagsProvider } from './components/feature-flags-provider.react.js'; +import IdentityHandler from './components/identity-handler.react.js'; import PersistedStateGate from './components/persisted-state-gate.js'; import VersionSupportedChecker from './components/version-supported.react.js'; import ConnectedStatusBar from './connected-status-bar.react.js'; @@ -75,7 +76,6 @@ import ThemeHandler from './themes/theme-handler.react.js'; import { provider } from './utils/ethers-utils.js'; import { useTunnelbrokerInitMessage } from './utils/tunnelbroker-utils.js'; - // Add custom items to expo-dev-menu import './dev-menu.js'; import './types/message-types-validator.js'; @@ -328,6 +328,7 @@ } /> + {navigation}