Page MenuHomePhabricator

D7749.id26454.diff
No OneTemporary

D7749.id26454.diff

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
@@ -37,6 +37,7 @@
clientSocketMessageTypes,
stateSyncPayloadTypes,
serverSocketMessageTypes,
+ serverServerSocketMessageValidator,
} from 'lib/types/socket-types.js';
import { ServerError } from 'lib/utils/errors.js';
import { values } from 'lib/utils/objects.js';
@@ -86,6 +87,7 @@
checkInputValidator,
checkClientSupported,
policiesValidator,
+ validateOutput,
} from '../utils/validation-utils.js';
const clientSocketMessageInputValidator = t.union([
@@ -375,7 +377,13 @@
"shouldn't send message until connection established",
);
if (this.ws.readyState === 1) {
- this.ws.send(JSON.stringify(message));
+ const { viewer } = this;
+ const validatedMessage = validateOutput(
+ viewer,
+ serverServerSocketMessageValidator,
+ message,
+ );
+ this.ws.send(JSON.stringify(validatedMessage));
}
};
diff --git a/keyserver/src/utils/validation-utils.js b/keyserver/src/utils/validation-utils.js
--- a/keyserver/src/utils/validation-utils.js
+++ b/keyserver/src/utils/validation-utils.js
@@ -50,7 +50,7 @@
}
function validateOutput<T>(
- viewer: Viewer,
+ viewer: ?Viewer,
outputValidator: TType<T>,
data: T,
): T {
@@ -63,8 +63,8 @@
}
if (
- hasMinCodeVersion(viewer.platformDetails, 1000) &&
- !isWebPlatform(viewer.platformDetails?.platform) &&
+ hasMinCodeVersion(viewer?.platformDetails, 1000) &&
+ !isWebPlatform(viewer?.platformDetails?.platform) &&
convertToNewIDSchema
) {
return convertServerIDsToClientIDs(
diff --git a/lib/types/message-types.js b/lib/types/message-types.js
--- a/lib/types/message-types.js
+++ b/lib/types/message-types.js
@@ -588,6 +588,12 @@
+truncationStatuses: MessageTruncationStatuses,
+currentAsOf: number,
};
+export const messagesResponseValidator: TInterface<MessagesResponse> =
+ tShape<MessagesResponse>({
+ rawMessageInfos: t.list(rawMessageInfoValidator),
+ truncationStatuses: messageTruncationStatusesValidator,
+ currentAsOf: t.Number,
+ });
export type SimpleMessagesPayload = {
+rawMessageInfos: $ReadOnlyArray<RawMessageInfo>,
+truncationStatuses: MessageTruncationStatuses,
@@ -673,6 +679,10 @@
export type NewMessagesPayload = {
+messagesResult: MessagesResponse,
};
+export const newMessagesPayloadValidator: TInterface<NewMessagesPayload> =
+ tShape<NewMessagesPayload>({
+ messagesResult: messagesResponseValidator,
+ });
export type MessageStorePrunePayload = {
+threadIDs: $ReadOnlyArray<string>,
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
@@ -1,24 +1,33 @@
// @flow
import invariant from 'invariant';
+import t, { type TUnion } from 'tcomb';
import { type ActivityUpdate } from './activity-types.js';
import type { Shape } from './core.js';
import type { SignedIdentityKeysBlob } from './crypto-types.js';
import type { Platform, PlatformDetails } from './device-types.js';
-import type { RawEntryInfo, CalendarQuery } from './entry-types.js';
+import {
+ type RawEntryInfo,
+ type CalendarQuery,
+ rawEntryInfoValidator,
+} from './entry-types.js';
import type {
ThreadInconsistencyReportShape,
EntryInconsistencyReportShape,
ClientThreadInconsistencyReportShape,
ClientEntryInconsistencyReportShape,
} from './report-types.js';
-import type { RawThreadInfo } from './thread-types.js';
-import type {
- CurrentUserInfo,
- OldCurrentUserInfo,
- AccountUserInfo,
+import { type RawThreadInfo, rawThreadInfoValidator } from './thread-types.js';
+import {
+ type CurrentUserInfo,
+ currentUserInfoValidator,
+ type OldCurrentUserInfo,
+ oldCurrentUserInfoValidator,
+ type AccountUserInfo,
+ accountUserInfoValidator,
} from './user-types.js';
+import { tNumber, tShape, tID } 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".
@@ -55,6 +64,9 @@
type PlatformServerRequest = {
+type: 0,
};
+const platformServerRequestValidator = tShape<PlatformServerRequest>({
+ type: tNumber(serverRequestTypes.PLATFORM),
+});
type PlatformClientResponse = {
+type: 0,
+platform: Platform,
@@ -68,6 +80,11 @@
type PlatformDetailsServerRequest = {
type: 3,
};
+const platformDetailsServerRequestValidator =
+ tShape<PlatformDetailsServerRequest>({
+ type: tNumber(serverRequestTypes.PLATFORM_DETAILS),
+ });
+
type PlatformDetailsClientResponse = {
type: 3,
platformDetails: PlatformDetails,
@@ -96,6 +113,32 @@
+deleteUserInfoIDs: string[],
}>,
};
+const serverCheckStateServerRequestValidator =
+ tShape<ServerCheckStateServerRequest>({
+ type: tNumber(serverRequestTypes.CHECK_STATE),
+ hashesToCheck: t.dict(t.String, t.Number),
+ failUnmentioned: t.maybe(
+ tShape({
+ threadInfos: t.maybe(t.Boolean),
+ entryInfos: t.maybe(t.Boolean),
+ userInfos: t.maybe(t.Boolean),
+ }),
+ ),
+ stateChanges: t.maybe(
+ tShape({
+ rawThreadInfos: t.maybe(t.list(rawThreadInfoValidator)),
+ rawEntryInfos: t.maybe(t.list(rawEntryInfoValidator)),
+ currentUserInfo: t.maybe(
+ t.union([currentUserInfoValidator, oldCurrentUserInfoValidator]),
+ ),
+ userInfos: t.maybe(t.list(accountUserInfoValidator)),
+ deleteThreadIDs: t.maybe(t.list(tID)),
+ deleteEntryIDs: t.maybe(t.list(tID)),
+ deleteUserInfoIDs: t.maybe(t.list(t.String)),
+ }),
+ ),
+ });
+
type CheckStateClientResponse = {
+type: 6,
+hashResults: { +[key: string]: boolean },
@@ -109,6 +152,11 @@
type MoreOneTimeKeysServerRequest = {
+type: 8,
};
+const moreOneTimeKeysServerRequestValidator =
+ tShape<MoreOneTimeKeysServerRequest>({
+ type: tNumber(serverRequestTypes.MORE_ONE_TIME_KEYS),
+ });
+
type MoreOneTimeKeysClientResponse = {
+type: 8,
+keys: $ReadOnlyArray<string>,
@@ -117,6 +165,11 @@
type SignedIdentityKeysBlobServerRequest = {
+type: 9,
};
+const signedIdentityKeysBlobServerRequestValidator =
+ tShape<SignedIdentityKeysBlobServerRequest>({
+ type: tNumber(serverRequestTypes.SIGNED_IDENTITY_KEYS_BLOB),
+ });
+
type SignedIdentityKeysBlobClientResponse = {
+type: 9,
+signedIdentityKeysBlob: SignedIdentityKeysBlob,
@@ -128,6 +181,15 @@
| ServerCheckStateServerRequest
| MoreOneTimeKeysServerRequest
| SignedIdentityKeysBlobServerRequest;
+export const serverServerRequestValidator: TUnion<ServerServerRequest> =
+ t.union([
+ platformServerRequestValidator,
+ platformDetailsServerRequestValidator,
+ serverCheckStateServerRequestValidator,
+ moreOneTimeKeysServerRequestValidator,
+ signedIdentityKeysBlobServerRequestValidator,
+ ]);
+
export type ClientResponse =
| PlatformClientResponse
| ThreadInconsistencyClientResponse
diff --git a/lib/types/socket-types.js b/lib/types/socket-types.js
--- a/lib/types/socket-types.js
+++ b/lib/types/socket-types.js
@@ -1,39 +1,55 @@
// @flow
import invariant from 'invariant';
+import t, { type TInterface, type TUnion } from 'tcomb';
import {
type ActivityUpdate,
type UpdateActivityResult,
+ updateActivityResultValidator,
} from './activity-types.js';
import type { Platform } from './device-types.js';
import type { APIRequest } from './endpoints.js';
import {
type RawEntryInfo,
+ rawEntryInfoValidator,
type CalendarQuery,
defaultCalendarQuery,
} from './entry-types.js';
-import type { MessagesResponse, NewMessagesPayload } from './message-types.js';
-import type {
- ServerServerRequest,
- ClientServerRequest,
- ClientResponse,
- ClientClientResponse,
+import {
+ type MessagesResponse,
+ messagesResponseValidator,
+ type NewMessagesPayload,
+ newMessagesPayloadValidator,
+} from './message-types.js';
+import {
+ type ServerServerRequest,
+ serverServerRequestValidator,
+ type ClientServerRequest,
+ type ClientResponse,
+ type ClientClientResponse,
} from './request-types.js';
import type { SessionState, SessionIdentification } from './session-types.js';
-import type { RawThreadInfo } from './thread-types.js';
-import type {
- ClientUpdatesResult,
- ClientUpdatesResultWithUserInfos,
- ServerUpdatesResult,
- ServerUpdatesResultWithUserInfos,
+import { type RawThreadInfo, rawThreadInfoValidator } from './thread-types.js';
+import {
+ type ClientUpdatesResult,
+ type ClientUpdatesResultWithUserInfos,
+ type ServerUpdatesResult,
+ serverUpdatesResultValidator,
+ type ServerUpdatesResultWithUserInfos,
+ serverUpdatesResultWithUserInfosValidator,
} from './update-types.js';
-import type {
- UserInfo,
- CurrentUserInfo,
- OldCurrentUserInfo,
- LoggedOutUserInfo,
+import {
+ type UserInfo,
+ userInfoValidator,
+ type CurrentUserInfo,
+ currentUserInfoValidator,
+ type OldCurrentUserInfo,
+ oldCurrentUserInfoValidator,
+ type LoggedOutUserInfo,
+ loggedOutUserInfoValidator,
} from './user-types.js';
+import { tShape, tNumber, tID } from '../utils/validation-utils.js';
// The types of messages that the client sends across the socket
export const clientSocketMessageTypes = Object.freeze({
@@ -169,6 +185,13 @@
+userInfos: $ReadOnlyArray<UserInfo>,
+updatesCurrentAsOf: number,
};
+const baseFullStateSyncValidator = tShape<BaseFullStateSync>({
+ messagesResult: messagesResponseValidator,
+ threadInfos: t.dict(tID, rawThreadInfoValidator),
+ rawEntryInfos: t.list(rawEntryInfoValidator),
+ userInfos: t.list(userInfoValidator),
+ updatesCurrentAsOf: t.Number,
+});
export type ClientFullStateSync = {
...BaseFullStateSync,
@@ -189,12 +212,26 @@
...BaseFullStateSync,
+currentUserInfo: CurrentUserInfo | OldCurrentUserInfo,
};
+const serverFullStateSyncValidator = tShape<ServerFullStateSync>({
+ ...baseFullStateSyncValidator.meta.props,
+ currentUserInfo: t.union([
+ currentUserInfoValidator,
+ oldCurrentUserInfoValidator,
+ ]),
+});
+
export type ServerStateSyncFullSocketPayload = {
...ServerFullStateSync,
+type: 0,
// Included iff client is using sessionIdentifierTypes.BODY_SESSION_ID
+sessionID?: string,
};
+const serverStateSyncFullSocketPayloadValidator =
+ tShape<ServerStateSyncFullSocketPayload>({
+ ...serverFullStateSyncValidator.meta.props,
+ type: tNumber(stateSyncPayloadTypes.FULL),
+ sessionID: t.maybe(t.String),
+ });
export const incrementalStateSyncActionType = 'INCREMENTAL_STATE_SYNC';
export type BaseIncrementalStateSync = {
@@ -203,6 +240,12 @@
+deletedEntryIDs: $ReadOnlyArray<string>,
+userInfos: $ReadOnlyArray<UserInfo>,
};
+const baseIncrementalStateSyncValidator = tShape<BaseIncrementalStateSync>({
+ messagesResult: messagesResponseValidator,
+ deltaEntryInfos: t.list(rawEntryInfoValidator),
+ deletedEntryIDs: t.list(tID),
+ userInfos: t.list(userInfoValidator),
+});
export type ClientIncrementalStateSync = {
...BaseIncrementalStateSync,
@@ -221,10 +264,20 @@
...BaseIncrementalStateSync,
+updatesResult: ServerUpdatesResult,
};
+const serverIncrementalStateSyncValidator = tShape<ServerIncrementalStateSync>({
+ ...baseIncrementalStateSyncValidator.meta.props,
+ updatesResult: serverUpdatesResultValidator,
+});
+
type ServerStateSyncIncrementalSocketPayload = {
+type: 1,
...ServerIncrementalStateSync,
};
+const serverStateSyncIncrementalSocketPayloadValidator =
+ tShape<ServerStateSyncIncrementalSocketPayload>({
+ type: tNumber(stateSyncPayloadTypes.INCREMENTAL),
+ ...serverIncrementalStateSyncValidator.meta.props,
+ });
export type ClientStateSyncSocketPayload =
| ClientStateSyncFullSocketPayload
@@ -232,12 +285,23 @@
export type ServerStateSyncSocketPayload =
| ServerStateSyncFullSocketPayload
| ServerStateSyncIncrementalSocketPayload;
+const serverStateSyncSocketPayloadValidator = t.union([
+ serverStateSyncFullSocketPayloadValidator,
+ serverStateSyncIncrementalSocketPayloadValidator,
+]);
export type ServerStateSyncServerSocketMessage = {
+type: 0,
+responseTo: number,
+payload: ServerStateSyncSocketPayload,
};
+export const serverStateSyncServerSocketMessageValidator: TInterface<ServerStateSyncServerSocketMessage> =
+ tShape<ServerStateSyncServerSocketMessage>({
+ type: tNumber(serverSocketMessageTypes.STATE_SYNC),
+ responseTo: t.Number,
+ payload: serverStateSyncSocketPayloadValidator,
+ });
+
export type ServerRequestsServerSocketMessage = {
+type: 1,
+responseTo?: number,
@@ -245,12 +309,29 @@
+serverRequests: $ReadOnlyArray<ServerServerRequest>,
},
};
+export const serverRequestsServerSocketMessageValidator: TInterface<ServerRequestsServerSocketMessage> =
+ tShape<ServerRequestsServerSocketMessage>({
+ type: tNumber(serverSocketMessageTypes.REQUESTS),
+ responseTo: t.maybe(t.Number),
+ payload: tShape({
+ serverRequests: t.list(serverServerRequestValidator),
+ }),
+ });
+
export type ErrorServerSocketMessage = {
type: 2,
responseTo?: number,
message: string,
payload?: Object,
};
+export const errorServerSocketMessageValidator: TInterface<ErrorServerSocketMessage> =
+ tShape<ErrorServerSocketMessage>({
+ type: tNumber(serverSocketMessageTypes.ERROR),
+ responseTo: t.maybe(t.Number),
+ message: t.String,
+ payload: t.maybe(t.Object),
+ });
+
export type AuthErrorServerSocketMessage = {
type: 3,
responseTo: number,
@@ -262,28 +343,70 @@
currentUserInfo: LoggedOutUserInfo,
},
};
+export const authErrorServerSocketMessageValidator: TInterface<AuthErrorServerSocketMessage> =
+ tShape<AuthErrorServerSocketMessage>({
+ type: tNumber(serverSocketMessageTypes.AUTH_ERROR),
+ responseTo: t.Number,
+ message: t.String,
+ sessionChange: t.maybe(
+ tShape({ cookie: t.String, currentUserInfo: loggedOutUserInfoValidator }),
+ ),
+ });
+
export type ActivityUpdateResponseServerSocketMessage = {
+type: 4,
+responseTo: number,
+payload: UpdateActivityResult,
};
+export const activityUpdateResponseServerSocketMessageValidator: TInterface<ActivityUpdateResponseServerSocketMessage> =
+ tShape<ActivityUpdateResponseServerSocketMessage>({
+ type: tNumber(serverSocketMessageTypes.ACTIVITY_UPDATE_RESPONSE),
+ responseTo: t.Number,
+ payload: updateActivityResultValidator,
+ });
+
export type PongServerSocketMessage = {
+type: 5,
+responseTo: number,
};
+export const pongServerSocketMessageValidator: TInterface<PongServerSocketMessage> =
+ tShape<PongServerSocketMessage>({
+ type: tNumber(serverSocketMessageTypes.PONG),
+ responseTo: t.Number,
+ });
+
export type ServerUpdatesServerSocketMessage = {
+type: 6,
+payload: ServerUpdatesResultWithUserInfos,
};
+export const serverUpdatesServerSocketMessageValidator: TInterface<ServerUpdatesServerSocketMessage> =
+ tShape<ServerUpdatesServerSocketMessage>({
+ type: tNumber(serverSocketMessageTypes.UPDATES),
+ payload: serverUpdatesResultWithUserInfosValidator,
+ });
+
export type MessagesServerSocketMessage = {
+type: 7,
+payload: NewMessagesPayload,
};
+export const messagesServerSocketMessageValidator: TInterface<MessagesServerSocketMessage> =
+ tShape<MessagesServerSocketMessage>({
+ type: tNumber(serverSocketMessageTypes.MESSAGES),
+ payload: newMessagesPayloadValidator,
+ });
+
export type APIResponseServerSocketMessage = {
+type: 8,
+responseTo: number,
- +payload: Object,
-};
+ +payload?: Object,
+};
+export const apiResponseServerSocketMessageValidator: TInterface<APIResponseServerSocketMessage> =
+ tShape<APIResponseServerSocketMessage>({
+ type: tNumber(serverSocketMessageTypes.API_RESPONSE),
+ responseTo: t.Number,
+ payload: t.maybe(t.Object),
+ });
+
export type ServerServerSocketMessage =
| ServerStateSyncServerSocketMessage
| ServerRequestsServerSocketMessage
@@ -294,6 +417,18 @@
| ServerUpdatesServerSocketMessage
| MessagesServerSocketMessage
| APIResponseServerSocketMessage;
+export const serverServerSocketMessageValidator: TUnion<ServerServerSocketMessage> =
+ t.union([
+ serverStateSyncServerSocketMessageValidator,
+ serverRequestsServerSocketMessageValidator,
+ errorServerSocketMessageValidator,
+ authErrorServerSocketMessageValidator,
+ activityUpdateResponseServerSocketMessageValidator,
+ pongServerSocketMessageValidator,
+ serverUpdatesServerSocketMessageValidator,
+ messagesServerSocketMessageValidator,
+ apiResponseServerSocketMessageValidator,
+ ]);
export type ClientRequestsServerSocketMessage = {
+type: 1,
diff --git a/lib/types/update-types.js b/lib/types/update-types.js
--- a/lib/types/update-types.js
+++ b/lib/types/update-types.js
@@ -378,10 +378,21 @@
+currentAsOf: number,
+newUpdates: $ReadOnlyArray<ServerUpdateInfo>,
};
+export const serverUpdatesResultValidator: TInterface<ServerUpdatesResult> =
+ tShape<ServerUpdatesResult>({
+ currentAsOf: t.Number,
+ newUpdates: t.list(serverUpdateInfoValidator),
+ });
+
export type ServerUpdatesResultWithUserInfos = {
+updatesResult: ServerUpdatesResult,
+userInfos: $ReadOnlyArray<UserInfo>,
};
+export const serverUpdatesResultWithUserInfosValidator: TInterface<ServerUpdatesResultWithUserInfos> =
+ tShape<ServerUpdatesResultWithUserInfos>({
+ updatesResult: serverUpdatesResultValidator,
+ userInfos: t.list(userInfoValidator),
+ });
export type ClientUpdatesResult = {
+currentAsOf: number,
diff --git a/lib/types/user-types.js b/lib/types/user-types.js
--- a/lib/types/user-types.js
+++ b/lib/types/user-types.js
@@ -1,6 +1,6 @@
// @flow
-import t, { type TInterface, type TDict } from 'tcomb';
+import t, { type TInterface, type TDict, type TUnion } from 'tcomb';
import {
type DefaultNotificationPayload,
@@ -112,7 +112,16 @@
tShape<LoggedOutUserInfo>({ id: t.String, anonymous: tBool(true) });
export type OldCurrentUserInfo = OldLoggedInUserInfo | LoggedOutUserInfo;
+export const oldCurrentUserInfoValidator: TUnion<OldCurrentUserInfo> = t.union([
+ oldLoggedInUserInfoValidator,
+ loggedOutUserInfoValidator,
+]);
+
export type CurrentUserInfo = LoggedInUserInfo | LoggedOutUserInfo;
+export const currentUserInfoValidator: TUnion<CurrentUserInfo> = t.union([
+ loggedInUserInfoValidator,
+ loggedOutUserInfoValidator,
+]);
export type PasswordUpdate = {
+updatedFields: {
diff --git a/lib/types/validation.test.js b/lib/types/validation.test.js
--- a/lib/types/validation.test.js
+++ b/lib/types/validation.test.js
@@ -9,6 +9,18 @@
mediaValidator,
} from './media-types.js';
import { messageTypes } from './message-types-enum.js';
+import {
+ activityUpdateResponseServerSocketMessageValidator,
+ apiResponseServerSocketMessageValidator,
+ authErrorServerSocketMessageValidator,
+ errorServerSocketMessageValidator,
+ messagesServerSocketMessageValidator,
+ pongServerSocketMessageValidator,
+ serverRequestsServerSocketMessageValidator,
+ serverSocketMessageTypes,
+ serverStateSyncServerSocketMessageValidator,
+ serverUpdatesServerSocketMessageValidator,
+} from './socket-types.js';
import { threadTypes, rawThreadInfoValidator } from './thread-types.js';
import {
updateTypes,
@@ -667,71 +679,71 @@
});
});
-describe('server update validation', () => {
- const updates = [
- {
- type: updateTypes.DELETE_ACCOUNT,
- id: '98424',
- time: 1640870111106,
- deletedUserID: '98262',
- },
- {
- type: updateTypes.UPDATE_THREAD,
- id: '97948',
- time: 1640868525494,
- threadInfo: thread,
- },
- {
- type: updateTypes.UPDATE_THREAD_READ_STATUS,
- id: '98002',
- time: 1640869373326,
- threadID: '83794',
- unread: true,
- },
- {
- type: updateTypes.DELETE_THREAD,
- id: '98208',
- time: 1640869773339,
- threadID: '97852',
- },
- {
- type: updateTypes.JOIN_THREAD,
- id: '98126',
- time: 1640869494461,
- threadInfo: thread,
- rawMessageInfos: messages,
- truncationStatus: 'exhaustive',
- rawEntryInfos: [entry],
- },
- {
- type: updateTypes.BAD_DEVICE_TOKEN,
- id: '98208',
- time: 1640869773495,
- deviceToken: 'some-device-token',
- },
- {
- type: updateTypes.UPDATE_ENTRY,
- id: '98233',
- time: 1640869844908,
- entryInfo: entry,
- },
- {
- type: updateTypes.UPDATE_CURRENT_USER,
- id: '98237',
- time: 1640869934058,
- currentUserInfo: {
- id: '256',
- username: 'ashoat',
- },
- },
- {
- type: updateTypes.UPDATE_USER,
- id: '97988',
- time: 1640869211822,
- updatedUserID: '86565',
+const updates = [
+ {
+ type: updateTypes.DELETE_ACCOUNT,
+ id: '98424',
+ time: 1640870111106,
+ deletedUserID: '98262',
+ },
+ {
+ type: updateTypes.UPDATE_THREAD,
+ id: '97948',
+ time: 1640868525494,
+ threadInfo: thread,
+ },
+ {
+ type: updateTypes.UPDATE_THREAD_READ_STATUS,
+ id: '98002',
+ time: 1640869373326,
+ threadID: '83794',
+ unread: true,
+ },
+ {
+ type: updateTypes.DELETE_THREAD,
+ id: '98208',
+ time: 1640869773339,
+ threadID: '97852',
+ },
+ {
+ type: updateTypes.JOIN_THREAD,
+ id: '98126',
+ time: 1640869494461,
+ threadInfo: thread,
+ rawMessageInfos: messages,
+ truncationStatus: 'exhaustive',
+ rawEntryInfos: [entry],
+ },
+ {
+ type: updateTypes.BAD_DEVICE_TOKEN,
+ id: '98208',
+ time: 1640869773495,
+ deviceToken: 'some-device-token',
+ },
+ {
+ type: updateTypes.UPDATE_ENTRY,
+ id: '98233',
+ time: 1640869844908,
+ entryInfo: entry,
+ },
+ {
+ type: updateTypes.UPDATE_CURRENT_USER,
+ id: '98237',
+ time: 1640869934058,
+ currentUserInfo: {
+ id: '256',
+ username: 'ashoat',
},
- ];
+ },
+ {
+ type: updateTypes.UPDATE_USER,
+ id: '97988',
+ time: 1640869211822,
+ updatedUserID: '86565',
+ },
+];
+describe('server update validation', () => {
const validatorByUpdateType = {
[updateTypes.DELETE_ACCOUNT]: accountDeletionUpdateInfoValidator,
[updateTypes.UPDATE_THREAD]: threadUpdateInfoValidator,
@@ -766,3 +778,126 @@
}
}
});
+
+describe('socket message validation', () => {
+ const socketMessages = [
+ {
+ type: serverSocketMessageTypes.STATE_SYNC,
+ responseTo: 0,
+ payload: {
+ type: 1,
+ messagesResult: {
+ rawMessageInfos: messages,
+ truncationStatuses: { '86033': 'unchanged' },
+ currentAsOf: 1683296863468,
+ },
+ updatesResult: {
+ newUpdates: updates,
+ currentAsOf: 1683296863489,
+ },
+ deltaEntryInfos: [],
+ deletedEntryIDs: [],
+ userInfos: [],
+ },
+ },
+ {
+ type: serverSocketMessageTypes.REQUESTS,
+ payload: {
+ serverRequests: [
+ {
+ type: 6,
+ hashesToCheck: {
+ threadInfos: 3311950643,
+ entryInfos: 3191324567,
+ currentUserInfo: 820850779,
+ userInfos: 707653884,
+ },
+ },
+ ],
+ },
+ },
+ {
+ type: serverSocketMessageTypes.ACTIVITY_UPDATE_RESPONSE,
+ responseTo: 194,
+ payload: { unfocusedToUnread: [] },
+ },
+ { type: serverSocketMessageTypes.PONG, responseTo: 190 },
+ {
+ type: 6,
+ payload: {
+ updatesResult: {
+ currentAsOf: 1683298141720,
+ newUpdates: [
+ {
+ type: 1,
+ id: '94428',
+ time: 1683298141720,
+ threadInfo: thread,
+ },
+ ],
+ },
+ userInfos: [],
+ },
+ },
+ {
+ type: serverSocketMessageTypes.MESSAGES,
+ payload: {
+ messagesResult: {
+ rawMessageInfos: messages,
+ truncationStatuses: { '86033': 'unchanged' },
+ currentAsOf: 1683298141707,
+ },
+ },
+ },
+ {
+ type: serverSocketMessageTypes.API_RESPONSE,
+ responseTo: 209,
+ payload: {
+ rawMessageInfos: messages,
+ truncationStatuses: { '1': 'exhaustive' },
+ userInfos: {},
+ },
+ },
+ ];
+
+ const validatorByMessageType = {
+ [serverSocketMessageTypes.STATE_SYNC]:
+ serverStateSyncServerSocketMessageValidator,
+ [serverSocketMessageTypes.REQUESTS]:
+ serverRequestsServerSocketMessageValidator,
+ [serverSocketMessageTypes.ERROR]: errorServerSocketMessageValidator,
+ [serverSocketMessageTypes.AUTH_ERROR]:
+ authErrorServerSocketMessageValidator,
+ [serverSocketMessageTypes.ACTIVITY_UPDATE_RESPONSE]:
+ activityUpdateResponseServerSocketMessageValidator,
+ [serverSocketMessageTypes.PONG]: pongServerSocketMessageValidator,
+ [serverSocketMessageTypes.UPDATES]:
+ serverUpdatesServerSocketMessageValidator,
+ [serverSocketMessageTypes.MESSAGES]: messagesServerSocketMessageValidator,
+ [serverSocketMessageTypes.API_RESPONSE]:
+ apiResponseServerSocketMessageValidator,
+ };
+
+ for (const validatorMessageType in validatorByMessageType) {
+ const validator = validatorByMessageType[validatorMessageType];
+ const validatorMessageTypeName = _findKey(
+ e => e === Number(validatorMessageType),
+ )(serverSocketMessageTypes);
+
+ for (const message of socketMessages) {
+ const messageTypeName = _findKey(e => e === message.type)(
+ serverSocketMessageTypes,
+ );
+
+ if (Number(validatorMessageType) === message.type) {
+ it(`${validatorMessageTypeName} should validate ${messageTypeName}`, () => {
+ expect(validator.is(message)).toBe(true);
+ });
+ } else {
+ it(`${validatorMessageTypeName} shouldn't validate ${messageTypeName}`, () => {
+ expect(validator.is(message)).toBe(false);
+ });
+ }
+ }
+ }
+});

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 30, 10:10 AM (20 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2600518
Default Alt Text
D7749.id26454.diff (25 KB)

Event Timeline