diff --git a/lib/utils/user-info-extraction-utils.js b/lib/utils/user-info-extraction-utils.js index 19e6531c4..5d80af0b0 100644 --- a/lib/utils/user-info-extraction-utils.js +++ b/lib/utils/user-info-extraction-utils.js @@ -1,46 +1,83 @@ // @flow import _memoize from 'lodash/memoize.js'; -import t, { type TType } from 'tcomb'; +import t, { type TType, type TInterface } from 'tcomb'; import type { CallSingleKeyserverEndpointResponse } from '../keyserver-conn/call-single-keyserver-endpoint.js'; import { mixedRawThreadInfoValidator } from '../permissions/minimally-encoded-raw-thread-info-validators.js'; import type { Endpoint } from '../types/endpoints.js'; +import type { MixedRawThreadInfos } from '../types/thread-types.js'; import { userInfoValidator } from '../types/user-types.js'; +import type { UserInfo } from '../types/user-types.js'; import { endpointValidators } from '../types/validators/endpoint-validators.js'; import { extractUserIDsFromPayload } from '../utils/conversion-utils.js'; import { tID, tShape } from '../utils/validation-utils.js'; -function extendResponderValidatorBase(inputValidator: TType<*>): TType<*> { - return tShape({ - ...inputValidator.meta.props, - cookieChange: t.maybe( - tShape({ - threadInfos: t.dict(tID, mixedRawThreadInfoValidator), - userInfos: t.list(userInfoValidator), - cookieInvalidated: t.maybe(t.Boolean), - sessionID: t.maybe(t.String), - cookie: t.maybe(t.String), - }), - ), - error: t.maybe(t.String), - payload: t.maybe(t.Object), - success: t.maybe(t.Boolean), - }); +type AdditionalCookieChange = { + +threadInfos: MixedRawThreadInfos, + +userInfos: $ReadOnlyArray, + +cookieInvalidated?: boolean, + sessionID?: string, + cookie?: string, +}; + +type AdditionalResponseFields = { + +cookieChange: AdditionalCookieChange, + +error?: string, + +payload?: Object, + +success: boolean, +}; + +const additionalResponseFieldsValidator = tShape({ + cookieChange: t.maybe( + tShape({ + threadInfos: t.dict(tID, mixedRawThreadInfoValidator), + userInfos: t.list(userInfoValidator), + cookieInvalidated: t.maybe(t.Boolean), + sessionID: t.maybe(t.String), + cookie: t.maybe(t.String), + }), + ), + error: t.maybe(t.String), + payload: t.maybe(t.Object), + success: t.maybe(t.Boolean), +}); + +function extendResponderValidatorBase(inputValidator: TType): TType { + if (inputValidator.meta.kind === 'union') { + const newTypes = []; + for (const innerValidator of inputValidator.meta.types) { + const newInnerValidator = extendResponderValidatorBase(innerValidator); + newTypes.push(newInnerValidator); + } + return t.union(newTypes); + } else if (inputValidator.meta.kind === 'interface') { + const recastValidator: TInterface = (inputValidator: any); + + return (tShape({ + ...recastValidator.meta.props, + ...additionalResponseFieldsValidator.meta.props, + }): any); + } else if (inputValidator.meta.kind === 'maybe') { + const typeObj = extendResponderValidatorBase(inputValidator.meta.type); + return (t.maybe(typeObj): any); + } + + return inputValidator; } const extendResponderValidator = _memoize(extendResponderValidatorBase); function extractAndPersistUserInfosFromEndpointResponse( message: CallSingleKeyserverEndpointResponse, endpoint: Endpoint, ): void { const extendedValidator = extendResponderValidator( endpointValidators[endpoint].validator, ); // eslint-disable-next-line no-unused-vars const newUserIDs = extractUserIDsFromPayload(extendedValidator, message); // TODO: dispatch an action adding the new user ids to the UserStore } export { extractAndPersistUserInfosFromEndpointResponse };