diff --git a/lib/actions/user-actions.js b/lib/actions/user-actions.js --- a/lib/actions/user-actions.js +++ b/lib/actions/user-actions.js @@ -120,12 +120,8 @@ ): ((logInInfo: LogInInfo) => Promise) => async logInInfo => { const watchedIDs = threadWatcher.getWatchedIDs(); - const { - logInActionSource, - primaryIdentityPublicKeys, - notificationIdentityPublicKeys, - ...restLogInInfo - } = logInInfo; + const { logInActionSource, signedIdentityKeysBlob, ...restLogInInfo } = + logInInfo; const response = await callServerEndpoint( 'log_in', 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 @@ -1,6 +1,6 @@ // @flow -import type { OLMIdentityKeys } from './crypto-types.js'; +import type { SignedIdentityKeysBlob } from './crypto-types.js'; import type { PlatformDetails } from './device-types.js'; import type { CalendarQuery, @@ -105,8 +105,7 @@ +calendarQuery: CalendarQuery, +deviceTokenUpdateRequest?: ?DeviceTokenUpdateRequest, +primaryIdentityPublicKey?: string, - +primaryIdentityPublicKeys?: ?OLMIdentityKeys, - +notificationIdentityPublicKeys?: ?OLMIdentityKeys, + +signedIdentityKeysBlob?: SignedIdentityKeysBlob, }; export type LogInInfo = { diff --git a/lib/types/crypto-types.js b/lib/types/crypto-types.js --- a/lib/types/crypto-types.js +++ b/lib/types/crypto-types.js @@ -16,3 +16,8 @@ +notificationAccount: ?PickledOLMAccount, +notificationIdentityKeys: ?OLMIdentityKeys, }; + +export type SignedIdentityKeysBlob = { + +payload: string, + +signature: string, +}; diff --git a/web/account/traditional-login-form.react.js b/web/account/traditional-login-form.react.js --- a/web/account/traditional-login-form.react.js +++ b/web/account/traditional-login-form.react.js @@ -1,5 +1,6 @@ // @flow +import olm from '@matrix-org/olm'; import invariant from 'invariant'; import * as React from 'react'; @@ -15,7 +16,11 @@ LogInStartingPayload, } from 'lib/types/account-types.js'; import { logInActionSources } 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, @@ -44,6 +49,9 @@ const notificationIdentityPublicKeys: ?OLMIdentityKeys = useSelector( state => state.cryptoStore.notificationIdentityKeys, ); + const primaryAccount: ?PickledOLMAccount = useSelector( + state => state.cryptoStore.primaryAccount, + ); const usernameInputRef = React.useRef(); React.useEffect(() => { @@ -79,14 +87,30 @@ notificationIdentityPublicKeys, 'notificationIdentityPublicKeys must be set in logInAction', ); + 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 result = await callLogIn({ ...extraInfo, username, password, logInActionSource: logInActionSources.logInFromWebForm, primaryIdentityPublicKey: primaryIdentityPublicKeys.ed25519, - primaryIdentityPublicKeys, - notificationIdentityPublicKeys, + signedIdentityKeysBlob, }); modalContext.popModal(); return result; @@ -107,6 +131,7 @@ modalContext, notificationIdentityPublicKeys, password, + primaryAccount, primaryIdentityPublicKeys, username, ], @@ -194,6 +219,8 @@ primaryIdentityPublicKeys === undefined || notificationIdentityPublicKeys === null || notificationIdentityPublicKeys === undefined || + primaryAccount === null || + primaryAccount === undefined || inputDisabled } onClick={onSubmit}