Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3387565
D7749.id26454.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
25 KB
Referenced Files
None
Subscribers
None
D7749.id26454.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D7749: [keyserver] Validate websocket output
Attached
Detach File
Event Timeline
Log In to Comment