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 @@ -392,6 +392,7 @@ deviceTokenUpdateRequest: t.maybe(deviceTokenUpdateRequestInputValidator), platformDetails: tPlatformDetails, watchedIDs: t.list(t.String), + signedIdentityKeysBlob: t.maybe(signedIdentityKeysBlobValidator), }); async function siweAuthResponder( diff --git a/web/account/siwe-login-form.react.js b/web/account/siwe-login-form.react.js --- a/web/account/siwe-login-form.react.js +++ b/web/account/siwe-login-form.react.js @@ -1,7 +1,7 @@ // @flow import '@rainbow-me/rainbowkit/styles.css'; - +import olm from '@matrix-org/olm'; import invariant from 'invariant'; import * as React from 'react'; import { useAccount, useSigner } from 'wagmi'; @@ -16,7 +16,11 @@ import SWMansionIcon from 'lib/components/SWMansionIcon.react.js'; import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; import type { LogInStartingPayload } from 'lib/types/account-types.js'; -import type { OLMIdentityKeys } from 'lib/types/crypto-types.js'; +import type { + OLMIdentityKeys, + PickledOLMAccount, + SignedIdentityKeysBlob, +} from 'lib/types/crypto-types.js'; import { useDispatchActionPromise, useServerCall, @@ -74,12 +78,24 @@ const primaryIdentityPublicKeys: ?OLMIdentityKeys = useSelector( state => state.cryptoStore.primaryIdentityKeys, ); + const notificationIdentityPublicKeys: ?OLMIdentityKeys = useSelector( + state => state.cryptoStore.notificationIdentityKeys, + ); + const primaryAccount: ?PickledOLMAccount = useSelector( + state => state.cryptoStore.primaryAccount, + ); const callSIWEAuthEndpoint = React.useCallback( - (message: string, signature: string, extraInfo) => + ( + message: string, + signature: string, + extraInfo, + signedIdentityKeysBlob: SignedIdentityKeysBlob, + ) => siweAuthCall({ message, signature, + signedIdentityKeysBlob, ...extraInfo, }), [siweAuthCall], @@ -87,15 +103,51 @@ const attemptSIWEAuth = React.useCallback( (message: string, signature: string) => { + invariant( + primaryIdentityPublicKeys, + 'primaryIdentityPublicKeys must be set in attemptSIWEAuth', + ); + invariant( + notificationIdentityPublicKeys, + 'notificationIdentityPublicKeys must be set in attemptSIWEAuth', + ); + invariant(primaryAccount, 'primaryAccount must be set in logInAction'); + + const primaryOLMAccount = new olm.Account(); + primaryOLMAccount.unpickle( + primaryAccount.picklingKey, + primaryAccount.pickledAccount, + ); + const payloadToBeSigned = JSON.stringify({ + primaryIdentityPublicKeys, + notificationIdentityPublicKeys, + }); + const signedIdentityKeysBlob: SignedIdentityKeysBlob = { + payload: payloadToBeSigned, + signature: primaryOLMAccount.sign(payloadToBeSigned), + }; + const extraInfo = logInExtraInfo(); dispatchActionPromise( siweAuthActionTypes, - callSIWEAuthEndpoint(message, signature, extraInfo), + callSIWEAuthEndpoint( + message, + signature, + extraInfo, + signedIdentityKeysBlob, + ), undefined, ({ calendarQuery: extraInfo.calendarQuery }: LogInStartingPayload), ); }, - [callSIWEAuthEndpoint, dispatchActionPromise, logInExtraInfo], + [ + callSIWEAuthEndpoint, + dispatchActionPromise, + logInExtraInfo, + notificationIdentityPublicKeys, + primaryAccount, + primaryIdentityPublicKeys, + ], ); const onSignInButtonClick = React.useCallback(async () => {