diff --git a/keyserver/src/creators/account-creator.js b/keyserver/src/creators/account-creator.js --- a/keyserver/src/creators/account-creator.js +++ b/keyserver/src/creators/account-creator.js @@ -71,7 +71,7 @@ WHERE LCASE(username) = LCASE(${request.username}) `; const promises = [dbQuery(usernameQuery)]; - const { calendarQuery } = request; + const { calendarQuery, publicKey, socialProof } = request; if (calendarQuery) { promises.push(verifyCalendarQueryThreadIDs(calendarQuery)); } @@ -103,6 +103,8 @@ createNewUserCookie(id, { platformDetails: request.platformDetails, deviceToken, + publicKey, + socialProof, }), deleteCookie(viewer.cookieID), dbQuery(newUserQuery), diff --git a/keyserver/src/responders/user-responders.js b/keyserver/src/responders/user-responders.js --- a/keyserver/src/responders/user-responders.js +++ b/keyserver/src/responders/user-responders.js @@ -201,7 +201,7 @@ const calendarQuery = request.calendarQuery ? normalizeCalendarQuery(request.calendarQuery) : null; - + const { publicKey, socialProof } = request; const newServerTime = Date.now(); const deviceToken = request.deviceTokenUpdateRequest ? request.deviceTokenUpdateRequest.deviceToken @@ -210,6 +210,8 @@ createNewUserCookie(userId, { platformDetails: request.platformDetails, deviceToken, + publicKey, + socialProof, }), deleteCookie(viewer.cookieID), ]); diff --git a/keyserver/src/session/cookies.js b/keyserver/src/session/cookies.js --- a/keyserver/src/session/cookies.js +++ b/keyserver/src/session/cookies.js @@ -642,8 +642,10 @@ } type UserCookieCreationParams = { - platformDetails: PlatformDetails, - deviceToken?: ?string, + +platformDetails: PlatformDetails, + +deviceToken?: ?string, + +publicKey?: ?string, + +socialProof?: ?string, }; // The result of this function should never be passed directly to the Viewer @@ -657,7 +659,7 @@ userID: string, params: UserCookieCreationParams, ): Promise { - const { platformDetails, deviceToken } = params; + const { platformDetails, deviceToken, publicKey, socialProof } = params; const { platform, ...versions } = platformDetails || defaultPlatformDetails; const versionsString = Object.keys(versions).length > 0 ? JSON.stringify(versions) : null; @@ -679,10 +681,12 @@ time, deviceToken, versionsString, + publicKey, + socialProof, ]; const query = SQL` INSERT INTO cookies(id, hash, user, platform, creation_time, last_used, - device_token, versions) + device_token, versions, public_key, social_proof) VALUES ${[cookieRow]} `; await dbQuery(query); diff --git a/landing/siwe.react.js b/landing/siwe.react.js --- a/landing/siwe.react.js +++ b/landing/siwe.react.js @@ -37,13 +37,13 @@ provider, }); -function createSiweMessage(address, statement) { +function createSiweMessage(address) { const domain = window.location.host; const origin = window.location.origin; const message = new SiweMessage({ domain, address, - statement, + statement: `Sign in to Comm with Ethereum. public_key:${window.ReactNativeWebView?.injectedPublicKey}`, uri: origin, version: '1', chainId: '1', @@ -52,7 +52,7 @@ } async function signInWithEthereum(address, signer) { - const message = createSiweMessage(address, 'Sign in to Comm with Ethereum'); + const message = createSiweMessage(address); const signature = await signer.signMessage(message); const messageToPost = JSON.stringify({ address, message, signature }); window.ReactNativeWebView?.postMessage?.(messageToPost); diff --git a/lib/types/account-types.js b/lib/types/account-types.js --- a/lib/types/account-types.js +++ b/lib/types/account-types.js @@ -51,6 +51,8 @@ +deviceTokenUpdateRequest?: ?DeviceTokenUpdateRequest, +platformDetails: PlatformDetails, +address?: ?string, + +publicKey?: ?string, + +socialProof?: ?string, }; export type RegisterResponse = { @@ -116,6 +118,8 @@ +platformDetails: PlatformDetails, +watchedIDs: $ReadOnlyArray, +source?: LogInActionSource, + +publicKey?: ?string, + +socialProof?: ?string, }; export type LogInResponse = { @@ -149,6 +153,8 @@ +deviceTokenUpdateRequest?: ?DeviceTokenUpdateRequest, +platformDetails: PlatformDetails, +watchedIDs: $ReadOnlyArray, + +publicKey?: ?string, + +socialProof?: ?string, }; export type SIWEServerCall = { @@ -160,9 +166,7 @@ export type SIWEResponse = RegisterResponse | LogInResponse; -export type SIWEResult = { - ...RegisterResult, -}; +export type SIWEResult = RegisterResult | LogInResult; export type UpdatePasswordRequest = { code: string, password: string, diff --git a/native/account/logged-out-modal.react.js b/native/account/logged-out-modal.react.js --- a/native/account/logged-out-modal.react.js +++ b/native/account/logged-out-modal.react.js @@ -30,6 +30,7 @@ addKeyboardDismissListener, removeKeyboardListener, } from '../keyboard/keyboard'; +import { commCoreModule } from '../native-modules'; import { createIsForegroundSelector } from '../navigation/nav-selectors'; import { NavContext } from '../navigation/navigation-context'; import { LoggedOutModalRouteName } from '../navigation/route-names'; @@ -59,7 +60,6 @@ import RegisterPanel from './register-panel.react'; import type { RegisterState } from './register-panel.react'; import SIWEPanel from './siwe-panel.react'; - let initialAppLoad = true; const safeAreaEdges = ['top', 'bottom']; @@ -279,7 +279,7 @@ return; } initialAppLoad = false; - + commCoreModule.initializeCryptoAccount(`stringThatIsn'tUsedAnywhere`); const { loggedIn, cookie, urlPrefix, dispatch } = this.props; const hasUserCookie = cookie && cookie.startsWith('user='); if (loggedIn === !!hasUserCookie) { diff --git a/native/account/siwe-panel.react.js b/native/account/siwe-panel.react.js --- a/native/account/siwe-panel.react.js +++ b/native/account/siwe-panel.react.js @@ -16,11 +16,11 @@ type DispatchActionPromise, } from 'lib/utils/action-utils'; +import { commCoreModule } from '../native-modules'; import { NavContext } from '../navigation/navigation-context'; import { useSelector } from '../redux/redux-utils'; import { nativeLogInExtraInfoSelector } from '../selectors/account-selectors'; import { defaultLandingURLPrefix } from '../utils/url-utils'; - const commSIWE = `${defaultLandingURLPrefix}/siwe`; type BaseProps = { @@ -37,15 +37,28 @@ +siweAction: (siweInfo: SIWEServerCall) => Promise, }; +type WebViewProps = { + injectJavaScript: (script: string) => void, +}; + function SIWEPanel({ logInExtraInfo, dispatchActionPromise, siweAction, }: Props) { + // $FlowFixMe + const webviewRef: React.Ref = React.useRef(); + async function setKey() { + const { ed25519 } = await commCoreModule.getUserPublicKey(); + // $FlowFixMe + webviewRef.current.injectJavascript( + `window.ReactNativeWebView.injectedPublicKey = ${ed25519}`, + ); + } const handleSIWE = React.useCallback( - ({ address, message, signature }) => { - // this is all mocked from register-panel + async ({ address, message, signature }) => { const extraInfo = logInExtraInfo(); + await commCoreModule.initializeCryptoAccount(address); dispatchActionPromise( siweActionTypes, siweAction({ @@ -73,7 +86,14 @@ [handleSIWE], ); const source = React.useMemo(() => ({ uri: commSIWE }), []); - return ; + return ( + + ); } const ConnectedSIWEPanel: React.ComponentType = React.memo( function ConnectedRegisterPanel(props: BaseProps) { diff --git a/native/schema/CommCoreModuleSchema.js b/native/schema/CommCoreModuleSchema.js --- a/native/schema/CommCoreModuleSchema.js +++ b/native/schema/CommCoreModuleSchema.js @@ -18,6 +18,10 @@ +key: string, +text: string, }; +type ClientPublicKeys = { + +curve25519: string, + +ed25519: string, +}; export interface Spec extends TurboModule { +getDraft: (key: string) => Promise; @@ -42,7 +46,7 @@ operations: $ReadOnlyArray, ) => void; +initializeCryptoAccount: (userId: string) => Promise; - +getUserPublicKey: () => Promise; + +getUserPublicKey: () => Promise; +getUserOneTimeKeys: () => Promise; +openSocket: (endpoint: string) => Object; +getCodeVersion: () => number; diff --git a/native/utils/url-utils.js b/native/utils/url-utils.js --- a/native/utils/url-utils.js +++ b/native/utils/url-utils.js @@ -40,6 +40,7 @@ return getDevNodeServerURLFromHostname(hostname); } +// the SIWE message prompt hangs indefinitely if it doesn't originate from HTTPs const canRainbowKitSignOverHTTPYet = false; function getDevLandingURL(): string {