diff --git a/keyserver/src/uploads/uploads.js b/keyserver/src/uploads/uploads.js --- a/keyserver/src/uploads/uploads.js +++ b/keyserver/src/uploads/uploads.js @@ -4,16 +4,17 @@ import invariant from 'invariant'; import multer from 'multer'; import { Readable } from 'stream'; -import t from 'tcomb'; +import t, { type TInterface } from 'tcomb'; -import type { - UploadMediaMetadataRequest, - UploadMultimediaResult, - UploadDeletionRequest, - Dimensions, +import { + type UploadMediaMetadataRequest, + type UploadMultimediaResult, + uploadMultimediaResultValidator, + type UploadDeletionRequest, + type Dimensions, } from 'lib/types/media-types.js'; import { ServerError } from 'lib/utils/errors.js'; -import { tShape } from 'lib/utils/validation-utils.js'; +import { tShape, tID } from 'lib/utils/validation-utils.js'; import { getMediaType, validateAndConvert } from './media-utils.js'; import type { UploadInput } from '../creators/upload-creator.js'; @@ -26,7 +27,7 @@ } from '../fetchers/upload-fetchers.js'; import type { MulterRequest } from '../responders/handlers.js'; import type { Viewer } from '../session/viewer.js'; -import { validateInput } from '../utils/validation-utils.js'; +import { validateInput, validateOutput } from '../utils/validation-utils.js'; const upload = multer(); const multerProcessor: Middleware<> = upload.array('multimedia'); @@ -34,6 +35,10 @@ type MultimediaUploadResult = { results: UploadMultimediaResult[], }; +const MultimediaUploadResultValidator = tShape({ + results: t.list(uploadMultimediaResultValidator), +}); + async function multimediaUploadResponder( viewer: Viewer, req: MulterRequest, @@ -97,10 +102,16 @@ throw new ServerError('invalid_parameters'); } const results = await createUploads(viewer, uploadInfos); - return { results }; + return validateOutput( + viewer.platformDetails, + MultimediaUploadResultValidator, + { + results, + }, + ); } -const uploadMediaMetadataInputValidator = tShape({ +const uploadMediaMetadataInputValidator = tShape({ filename: t.String, width: t.Number, height: t.Number, @@ -113,10 +124,13 @@ async function uploadMediaMetadataResponder( viewer: Viewer, - input: any, + input: mixed, ): Promise { - const request: UploadMediaMetadataRequest = input; - await validateInput(viewer, uploadMediaMetadataInputValidator, input); + const request = await validateInput( + viewer, + uploadMediaMetadataInputValidator, + input, + ); const mediaType = getMediaType(request.mimeType); if (!mediaType) { @@ -137,7 +151,11 @@ }; const [result] = await createUploads(viewer, [uploadInfo]); - return result; + return validateOutput( + viewer.platformDetails, + uploadMultimediaResultValidator, + result, + ); } async function uploadDownloadResponder( @@ -206,11 +224,20 @@ } } +const uploadDeletionRequestInputValidator: TInterface = + tShape({ + id: tID, + }); async function uploadDeletionResponder( viewer: Viewer, - request: UploadDeletionRequest, + input: mixed, ): Promise { - const { id } = request; + const { id } = await validateInput( + viewer, + uploadDeletionRequestInputValidator, + input, + ); + await deleteUpload(viewer, id); } diff --git a/lib/types/media-types.js b/lib/types/media-types.js --- a/lib/types/media-types.js +++ b/lib/types/media-types.js @@ -17,6 +17,7 @@ }); export type MediaType = 'photo' | 'video'; +const mediaTypeValidator = t.enums.of(['photo', 'video']); export type EncryptedMediaType = 'encrypted_photo' | 'encrypted_video'; @@ -64,6 +65,14 @@ +mediaType: MediaType, +loop: boolean, }; +export const uploadMultimediaResultValidator: TInterface = + tShape({ + id: tID, + uri: t.String, + dimensions: dimensionsValidator, + mediaType: mediaTypeValidator, + loop: t.Boolean, + }); export type UpdateMultimediaMessageMediaPayload = { +messageID: string,