diff --git a/keyserver/src/responders/version-responders.js b/keyserver/src/responders/version-responders.js --- a/keyserver/src/responders/version-responders.js +++ b/keyserver/src/responders/version-responders.js @@ -3,17 +3,38 @@ import t, { type TInterface } from 'tcomb'; import type { VersionResponse } from 'lib/types/device-types.js'; +import { getCommConfig } from 'lib/utils/comm-config.js'; import { tShape } from 'lib/utils/validation-utils.js'; +import type { UserCredentials } from '../user/checks.js'; +import { fetchIdentityInfo } from '../user/identity.js'; import { keyserverCodeVersion } from '../version.js'; export const versionResponseValidator: TInterface = - tShape({ codeVersion: t.Number }); - -const versionResponse = { codeVersion: keyserverCodeVersion }; + tShape({ + codeVersion: t.Number, + ownerUsername: t.maybe(t.String), + ownerID: t.maybe(t.String), + }); async function versionResponder(): Promise { - return versionResponse; + const userInfoPromise = getCommConfig({ + folder: 'secrets', + name: 'user_credentials', + }); + + const identityInfoPromise = fetchIdentityInfo(); + + const [userInfo, identityInfo] = await Promise.all([ + userInfoPromise, + identityInfoPromise, + ]); + + return { + codeVersion: keyserverCodeVersion, + ownerUsername: userInfo?.username, + ownerID: identityInfo?.userId, + }; } export { versionResponder }; diff --git a/keyserver/src/user/checks.js b/keyserver/src/user/checks.js --- a/keyserver/src/user/checks.js +++ b/keyserver/src/user/checks.js @@ -1,7 +1,7 @@ // @flow import { getCommConfig } from 'lib/utils/comm-config.js'; -type UserCredentials = { +username: string, +password: string }; +export type UserCredentials = { +username: string, +password: string }; async function ensureUserCredentials() { const userCredentials = await getCommConfig({ diff --git a/lib/actions/device-actions.js b/lib/actions/device-actions.js --- a/lib/actions/device-actions.js +++ b/lib/actions/device-actions.js @@ -1,10 +1,12 @@ // @flow -import type { VersionResponse } from '../types/device-types.js'; -import type { CallServerEndpoint } from '../utils/call-server-endpoint.js'; +import type { GetVersionActionPayload } from '../types/device-types'; import { getConfig } from '../utils/config.js'; -import type { CallKeyserverEndpoint } from '../utils/keyserver-call.js'; import { useKeyserverCall } from '../utils/keyserver-call.js'; +import type { + CallKeyserverEndpoint, + KeyserverCallParamOverride, +} from '../utils/keyserver-call.js'; export type DeviceTokens = { +[keyserverID: string]: ?string, @@ -71,15 +73,43 @@ success: 'GET_VERSION_SUCCESS', failed: 'GET_VERSION_FAILED', }); +// useGetVersion should be passed paramOverride containing keyserverInfos +// with entries for the keyservers we want to connect to. +// They should contain the urlPrefix of the keyserver. +// The key should also be the urlPrefix, +// since the id of the keyserver is not yet known. const getVersion = - (callServerEndpoint: CallServerEndpoint): (() => Promise) => + ( + callKeyserverEndpoint: CallKeyserverEndpoint, + allKeyserverIDs: $ReadOnlyArray, + ): (() => Promise) => async () => { - const response = await callServerEndpoint('version'); - return { - codeVersion: response.codeVersion, - }; + const requests = {}; + for (const keyserverID of allKeyserverIDs) { + requests[keyserverID] = {}; + } + + const responses = await callKeyserverEndpoint('version', requests); + + const result = { versionResponses: {} }; + for (const keyserverID in responses) { + const { codeVersion, ownerUsername, ownerID } = responses[keyserverID]; + result.versionResponses[ownerID] = { + codeVersion, + ownerUsername, + ownerID, + }; + } + + return result; }; +function useGetVersion( + paramOverride?: ?KeyserverCallParamOverride, +): () => Promise { + return useKeyserverCall(getVersion, paramOverride); +} + const updateLastCommunicatedPlatformDetailsActionType = 'UPDATE_LAST_COMMUNICATED_PLATFORM_DETAILS'; @@ -88,6 +118,6 @@ useSetDeviceToken, useSetDeviceTokenFanout, getVersionActionTypes, - getVersion, + useGetVersion, updateLastCommunicatedPlatformDetailsActionType, }; diff --git a/lib/types/device-types.js b/lib/types/device-types.js --- a/lib/types/device-types.js +++ b/lib/types/device-types.js @@ -43,4 +43,10 @@ export type VersionResponse = { +codeVersion: number, + +ownerUsername: ?string, + +ownerID: ?string, +}; + +export type GetVersionActionPayload = { + +versionResponses: { +[keyserverId: string]: VersionResponse }, }; diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js --- a/lib/types/redux-types.js +++ b/lib/types/redux-types.js @@ -18,7 +18,10 @@ UpdateUserAvatarResponse, } from './avatar-types.js'; import type { CryptoStore } from './crypto-types.js'; -import type { VersionResponse, PlatformDetails } from './device-types.js'; +import type { + GetVersionActionPayload, + PlatformDetails, +} from './device-types.js'; import type { ClientDBDraftInfo, DraftStore } from './draft-types.js'; import type { EnabledApps, SupportedApps } from './enabled-apps.js'; import type { @@ -1165,7 +1168,7 @@ } | { +type: 'GET_VERSION_SUCCESS', - +payload: VersionResponse, + +payload: GetVersionActionPayload, +loadingInfo: LoadingInfo, } | { diff --git a/lib/utils/keyserver-call.js b/lib/utils/keyserver-call.js --- a/lib/utils/keyserver-call.js +++ b/lib/utils/keyserver-call.js @@ -74,10 +74,12 @@ const createBoundServerCallsSelector: CreateBoundServerCallsSelectorType = (_memoize(baseCreateBoundServerCallsSelector): any); +export type KeyserverInfoPartial = $Shape; + export type BindKeyserverCallParams = { +dispatch: Dispatch, +currentUserInfo: ?CurrentUserInfo, - +keyserverInfos: { +[keyserverID: string]: KeyserverInfo }, + +keyserverInfos: { +[keyserverID: string]: KeyserverInfoPartial }, }; const bindCallKeyserverEndpointSelector = createSelector( @@ -115,7 +117,7 @@ cookie, urlPrefix, sessionID, - connectionStatus: connection.status, + connectionStatus: connection?.status, lastCommunicatedPlatformDetails, }); @@ -139,9 +141,11 @@ }, ); +export type KeyserverCallParamOverride = $Shape; + function useKeyserverCall( keyserverCall: ActionFunc, - paramOverride?: ?$Shape, + paramOverride?: ?KeyserverCallParamOverride, ): Args => Promise { const dispatch = useDispatch(); const keyserverInfos = useSelector( diff --git a/native/account/registration/keyserver-selection.react.js b/native/account/registration/keyserver-selection.react.js --- a/native/account/registration/keyserver-selection.react.js +++ b/native/account/registration/keyserver-selection.react.js @@ -5,14 +5,11 @@ import { Text, View } from 'react-native'; import { - getVersion, + useGetVersion, getVersionActionTypes, } from 'lib/actions/device-actions.js'; import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; -import { - useServerCall, - useDispatchActionPromise, -} from 'lib/utils/action-utils.js'; +import { useDispatchActionPromise } from 'lib/utils/action-utils.js'; import RegistrationButtonContainer from './registration-button-container.react.js'; import RegistrationButton from './registration-button.react.js'; @@ -112,11 +109,15 @@ const serverCallParamOverride = React.useMemo( () => ({ - urlPrefix: keyserverURL, + keyserverInfos: { + [keyserverURL]: { + urlPrefix: keyserverURL, + }, + }, }), [keyserverURL], ); - const getVersionCall = useServerCall(getVersion, serverCallParamOverride); + const getVersionCall = useGetVersion(serverCallParamOverride); const dispatchActionPromise = useDispatchActionPromise(); const { navigate } = props.navigation;