diff --git a/keyserver/src/responders/activity-responders.js b/keyserver/src/responders/activity-responders.js --- a/keyserver/src/responders/activity-responders.js +++ b/keyserver/src/responders/activity-responders.js @@ -47,8 +47,4 @@ return await setThreadUnreadStatus(viewer, request); } -export { - activityUpdatesInputValidator, - updateActivityResponder, - threadSetUnreadStatusResponder, -}; +export { updateActivityResponder, threadSetUnreadStatusResponder }; diff --git a/keyserver/src/responders/report-responders.js b/keyserver/src/responders/report-responders.js --- a/keyserver/src/responders/report-responders.js +++ b/keyserver/src/responders/report-responders.js @@ -2,23 +2,21 @@ import type { $Response, $Request } from 'express'; import t from 'tcomb'; -import type { TInterface, TStructProps, TUnion } from 'tcomb'; +import type { TInterface, TUnion } from 'tcomb'; -import { calendarQueryValidator } from 'lib/types/entry-types.js'; -import type { BaseAction } from 'lib/types/redux-types.js'; import { type ReportCreationResponse, type ReportCreationRequest, type FetchErrorReportInfosResponse, type FetchErrorReportInfosRequest, - type ThreadInconsistencyReportShape, - type EntryInconsistencyReportShape, - type ActionSummary, type ThreadInconsistencyReportCreationRequest, type EntryInconsistencyReportCreationRequest, type MediaMissionReportCreationRequest, type UserInconsistencyReportCreationRequest, reportTypes, + threadInconsistencyReportValidatorShape, + entryInconsistencyReportValidatorShape, + userInconsistencyReportValidatorShape, } from 'lib/types/report-types.js'; import { ServerError } from 'lib/utils/errors.js'; import { tShape, tPlatformDetails } from 'lib/utils/validation-utils.js'; @@ -30,47 +28,6 @@ } from '../fetchers/report-fetchers.js'; import type { Viewer } from '../session/viewer.js'; -const tActionSummary = tShape({ - type: t.String, - time: t.Number, - summary: t.String, -}); -const tActionType = t.irreducible<$PropertyType>( - 'ActionType', - x => typeof x === 'string', -); -const threadInconsistencyReportValidatorShape: TStructProps = - { - platformDetails: tPlatformDetails, - beforeAction: t.Object, - action: t.Object, - pollResult: t.maybe(t.Object), - pushResult: t.Object, - lastActionTypes: t.maybe(t.list(tActionType)), - lastActions: t.maybe(t.list(tActionSummary)), - time: t.maybe(t.Number), - }; -const entryInconsistencyReportValidatorShape: TStructProps = - { - platformDetails: tPlatformDetails, - beforeAction: t.Object, - action: t.Object, - calendarQuery: calendarQueryValidator, - pollResult: t.maybe(t.Object), - pushResult: t.Object, - lastActionTypes: t.maybe(t.list(tActionType)), - lastActions: t.maybe(t.list(tActionSummary)), - time: t.Number, - }; -const userInconsistencyReportValidatorShape = { - platformDetails: tPlatformDetails, - action: t.Object, - beforeStateCheck: t.Object, - afterStateCheck: t.Object, - lastActions: t.list(tActionSummary), - time: t.Number, -}; - const threadInconsistencyReportCreationRequest = tShape({ ...threadInconsistencyReportValidatorShape, diff --git a/keyserver/src/socket/session-utils.js b/keyserver/src/socket/session-utils.js --- a/keyserver/src/socket/session-utils.js +++ b/keyserver/src/socket/session-utils.js @@ -2,7 +2,6 @@ import invariant from 'invariant'; import t from 'tcomb'; -import type { TUnion } from 'tcomb'; import { hasMinCodeVersion } from 'lib/shared/version-utils.js'; import type { @@ -29,23 +28,12 @@ type ServerCheckStateServerRequest, } from 'lib/types/request-types.js'; import { sessionCheckFrequency } from 'lib/types/session-types.js'; -import { signedIdentityKeysBlobValidator } from 'lib/utils/crypto-utils.js'; import { hash, values } from 'lib/utils/objects.js'; import { promiseAll, ignorePromiseRejections } from 'lib/utils/promises.js'; -import { - tShape, - tPlatform, - tPlatformDetails, -} from 'lib/utils/validation-utils.js'; import { createAndPersistOlmSession } from '../creators/olm-session-creator.js'; import createReport from '../creators/report-creator.js'; import { fetchEntriesForSession } from '../fetchers/entry-fetchers.js'; -import { activityUpdatesInputValidator } from '../responders/activity-responders.js'; -import { - threadInconsistencyReportValidatorShape, - entryInconsistencyReportValidatorShape, -} from '../responders/report-responders.js'; import { setNewSession, setCookiePlatform, @@ -59,65 +47,6 @@ import type { SessionUpdate } from '../updaters/session-updaters.js'; import { getOlmUtility } from '../utils/olm-utils.js'; -const clientResponseInputValidator: TUnion = t.union([ - tShape({ - type: t.irreducible( - 'serverRequestTypes.PLATFORM', - x => x === serverRequestTypes.PLATFORM, - ), - platform: tPlatform, - }), - tShape({ - ...threadInconsistencyReportValidatorShape, - type: t.irreducible( - 'serverRequestTypes.THREAD_INCONSISTENCY', - x => x === serverRequestTypes.THREAD_INCONSISTENCY, - ), - }), - tShape({ - ...entryInconsistencyReportValidatorShape, - type: t.irreducible( - 'serverRequestTypes.ENTRY_INCONSISTENCY', - x => x === serverRequestTypes.ENTRY_INCONSISTENCY, - ), - }), - tShape({ - type: t.irreducible( - 'serverRequestTypes.PLATFORM_DETAILS', - x => x === serverRequestTypes.PLATFORM_DETAILS, - ), - platformDetails: tPlatformDetails, - }), - tShape({ - type: t.irreducible( - 'serverRequestTypes.CHECK_STATE', - x => x === serverRequestTypes.CHECK_STATE, - ), - hashResults: t.dict(t.String, t.Boolean), - }), - tShape({ - type: t.irreducible( - 'serverRequestTypes.INITIAL_ACTIVITY_UPDATES', - x => x === serverRequestTypes.INITIAL_ACTIVITY_UPDATES, - ), - activityUpdates: activityUpdatesInputValidator, - }), - tShape({ - type: t.irreducible( - 'serverRequestTypes.SIGNED_IDENTITY_KEYS_BLOB', - x => x === serverRequestTypes.SIGNED_IDENTITY_KEYS_BLOB, - ), - signedIdentityKeysBlob: signedIdentityKeysBlobValidator, - }), - tShape({ - type: t.irreducible( - 'serverRequestTypes.INITIAL_NOTIFICATIONS_ENCRYPTED_MESSAGE', - x => x === serverRequestTypes.INITIAL_NOTIFICATIONS_ENCRYPTED_MESSAGE, - ), - initialNotificationsEncryptedMessage: t.String, - }), -]); - type StateCheckStatus = | { status: 'state_validated' } | { status: 'state_invalid', invalidKeys: $ReadOnlyArray } @@ -527,9 +456,4 @@ } } -export { - clientResponseInputValidator, - processClientResponses, - initializeSession, - checkState, -}; +export { processClientResponses, initializeSession, checkState }; diff --git a/keyserver/src/socket/socket.js b/keyserver/src/socket/socket.js --- a/keyserver/src/socket/socket.js +++ b/keyserver/src/socket/socket.js @@ -23,7 +23,10 @@ } from 'lib/types/entry-types.js'; import { defaultNumberPerThread } from 'lib/types/message-types.js'; import { redisMessageTypes, type RedisMessage } from 'lib/types/redis-types.js'; -import { serverRequestTypes } from 'lib/types/request-types.js'; +import { + serverRequestTypes, + clientResponseInputValidator, +} from 'lib/types/request-types.js'; import { sessionCheckFrequency, stateCheckInactivityActivationInterval, @@ -55,7 +58,6 @@ import { RedisSubscriber } from './redis.js'; import { - clientResponseInputValidator, processClientResponses, initializeSession, checkState, diff --git a/lib/types/report-types.js b/lib/types/report-types.js --- a/lib/types/report-types.js +++ b/lib/types/report-types.js @@ -1,10 +1,14 @@ // @flow import invariant from 'invariant'; -import t, { type TInterface } from 'tcomb'; +import t, { type TInterface, type TStructProps } from 'tcomb'; import { type PlatformDetails } from './device-types.js'; -import { type RawEntryInfo, type CalendarQuery } from './entry-types.js'; +import { + type RawEntryInfo, + type CalendarQuery, + calendarQueryValidator, +} from './entry-types.js'; import { type MediaMission } from './media-types.js'; import type { AppState, BaseAction } from './redux-types.js'; import { type MixedRawThreadInfos } from './thread-types.js'; @@ -240,3 +244,46 @@ +preloadedState: AppState, +payload: $ReadOnlyArray, }; + +const tActionSummary = tShape({ + type: t.String, + time: t.Number, + summary: t.String, +}); +const tActionType = t.irreducible<$PropertyType>( + 'ActionType', + x => typeof x === 'string', +); + +export const threadInconsistencyReportValidatorShape: TStructProps = + { + platformDetails: tPlatformDetails, + beforeAction: t.Object, + action: t.Object, + pollResult: t.maybe(t.Object), + pushResult: t.Object, + lastActionTypes: t.maybe(t.list(tActionType)), + lastActions: t.maybe(t.list(tActionSummary)), + time: t.maybe(t.Number), + }; +export const entryInconsistencyReportValidatorShape: TStructProps = + { + platformDetails: tPlatformDetails, + beforeAction: t.Object, + action: t.Object, + calendarQuery: calendarQueryValidator, + pollResult: t.maybe(t.Object), + pushResult: t.Object, + lastActionTypes: t.maybe(t.list(tActionType)), + lastActions: t.maybe(t.list(tActionSummary)), + time: t.Number, + }; +export const userInconsistencyReportValidatorShape: TStructProps = + { + platformDetails: tPlatformDetails, + action: t.Object, + beforeStateCheck: t.Object, + afterStateCheck: t.Object, + lastActions: t.list(tActionSummary), + time: t.Number, + }; diff --git a/lib/types/request-types.js b/lib/types/request-types.js --- a/lib/types/request-types.js +++ b/lib/types/request-types.js @@ -3,7 +3,10 @@ import invariant from 'invariant'; import t, { type TUnion, type TInterface } from 'tcomb'; -import { type ActivityUpdate } from './activity-types.js'; +import { + type ActivityUpdate, + activityUpdateValidator, +} from './activity-types.js'; import type { SignedIdentityKeysBlob } from './crypto-types.js'; import { signedIdentityKeysBlobValidator } from './crypto-types.js'; import type { MessageSourceMetadata } from './db-ops-types.js'; @@ -14,11 +17,13 @@ rawEntryInfoValidator, } from './entry-types.js'; import type { RawThreadInfo } from './minimally-encoded-thread-permissions-types'; -import type { - ThreadInconsistencyReportShape, - EntryInconsistencyReportShape, - ClientThreadInconsistencyReportShape, - ClientEntryInconsistencyReportShape, +import { + type ThreadInconsistencyReportShape, + type EntryInconsistencyReportShape, + type ClientThreadInconsistencyReportShape, + type ClientEntryInconsistencyReportShape, + threadInconsistencyReportValidatorShape, + entryInconsistencyReportValidatorShape, } from './report-types.js'; import type { LegacyRawThreadInfo } from './thread-types.js'; import { @@ -28,7 +33,14 @@ accountUserInfoValidator, } from './user-types.js'; import { mixedRawThreadInfoValidator } from '../permissions/minimally-encoded-raw-thread-info-validators.js'; -import { tNumber, tShape, tID, tUserID } from '../utils/validation-utils.js'; +import { + tNumber, + tShape, + tID, + tUserID, + tPlatform, + tPlatformDetails, +} from '../utils/validation-utils.js'; // "Server requests" are requests for information that the server delivers to // clients. Clients then respond to those requests with a "client response". @@ -73,11 +85,21 @@ +type: 0, +platform: Platform, }; +const platformClientResponseValidator: TInterface = + tShape({ + type: tNumber(serverRequestTypes.PLATFORM), + platform: tPlatform, + }); export type ThreadInconsistencyClientResponse = { ...ThreadInconsistencyReportShape, +type: 2, }; +const threadInconsistencyClientResponseValidator: TInterface = + tShape({ + ...threadInconsistencyReportValidatorShape, + type: tNumber(serverRequestTypes.THREAD_INCONSISTENCY), + }); type PlatformDetailsServerRequest = { type: 3, @@ -91,11 +113,21 @@ type: 3, platformDetails: PlatformDetails, }; +const platformDetailsClientResponseValidator: TInterface = + tShape({ + type: tNumber(serverRequestTypes.PLATFORM_DETAILS), + platformDetails: tPlatformDetails, + }); export type EntryInconsistencyClientResponse = { type: 5, ...EntryInconsistencyReportShape, }; +const entryInconsistencyClientResponseValidator: TInterface = + tShape({ + ...entryInconsistencyReportValidatorShape, + type: tNumber(serverRequestTypes.ENTRY_INCONSISTENCY), + }); type FailUnmentioned = Partial<{ +threadInfos: boolean, @@ -147,11 +179,21 @@ +type: 6, +hashResults: { +[key: string]: boolean }, }; +const checkStateClientResponseValidator: TInterface = + tShape({ + type: tNumber(serverRequestTypes.CHECK_STATE), + hashResults: t.dict(t.String, t.Boolean), + }); type InitialActivityUpdatesClientResponse = { +type: 7, +activityUpdates: $ReadOnlyArray, }; +const initialActivityUpdatesClientResponseValidator: TInterface = + tShape({ + type: tNumber(serverRequestTypes.INITIAL_ACTIVITY_UPDATES), + activityUpdates: t.list(activityUpdateValidator), + }); type MoreOneTimeKeysClientResponse = { +type: 8, @@ -170,6 +212,11 @@ +type: 9, +signedIdentityKeysBlob: SignedIdentityKeysBlob, }; +const signedIdentityKeysBlobClientResponseValidator: TInterface = + tShape({ + type: tNumber(serverRequestTypes.SIGNED_IDENTITY_KEYS_BLOB), + signedIdentityKeysBlob: signedIdentityKeysBlobValidator, + }); type InitialNotificationsEncryptedMessageServerRequest = { +type: 10, @@ -183,6 +230,11 @@ +type: 10, +initialNotificationsEncryptedMessage: string, }; +const initialNotificationsEncryptedMessageClientResponseValidator: TInterface = + tShape({ + type: tNumber(serverRequestTypes.INITIAL_NOTIFICATIONS_ENCRYPTED_MESSAGE), + initialNotificationsEncryptedMessage: t.String, + }); export type ServerServerRequest = | PlatformServerRequest @@ -296,3 +348,14 @@ contentInitializationInfo: olmSessionInitializationInfoValidator, notifInitializationInfo: olmSessionInitializationInfoValidator, }); + +export const clientResponseInputValidator: TUnion = t.union([ + platformClientResponseValidator, + threadInconsistencyClientResponseValidator, + entryInconsistencyClientResponseValidator, + platformDetailsClientResponseValidator, + checkStateClientResponseValidator, + initialActivityUpdatesClientResponseValidator, + signedIdentityKeysBlobClientResponseValidator, + initialNotificationsEncryptedMessageClientResponseValidator, +]);