diff --git a/keyserver/src/uploads/media-utils.js b/keyserver/src/uploads/media-utils.js --- a/keyserver/src/uploads/media-utils.js +++ b/keyserver/src/uploads/media-utils.js @@ -30,6 +30,18 @@ }); } +function getMediaType(inputMimeType: string): 'photo' | 'video' | null { + if (!serverCanHandleTypes.has(inputMimeType)) { + return null; + } + const mediaType = mediaConfig[inputMimeType]?.mediaType; + invariant( + mediaType === 'photo' || mediaType === 'video', + `mediaType for ${inputMimeType} should be photo or video`, + ); + return mediaType; +} + type ValidateAndConvertInput = { +initialBuffer: Buffer, +initialName: string, @@ -63,14 +75,10 @@ 'inputDimensions should be set in validateAndConvert for encrypted files', ); - if (!serverCanHandleTypes.has(inputMimeType)) { + const mediaType = getMediaType(inputMimeType); + if (!mediaType) { return null; } - const mediaType = mediaConfig[inputMimeType]?.mediaType; - invariant( - mediaType === 'photo' || mediaType === 'video', - `mediaType for ${inputMimeType} should be photo or video`, - ); return { name: initialName, @@ -216,4 +224,4 @@ }; } -export { validateAndConvert }; +export { getMediaType, validateAndConvert }; 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,15 +4,19 @@ import invariant from 'invariant'; import multer from 'multer'; import { Readable } from 'stream'; +import t from 'tcomb'; import type { + UploadMediaMetadataRequest, UploadMultimediaResult, UploadDeletionRequest, Dimensions, } from 'lib/types/media-types.js'; import { ServerError } from 'lib/utils/errors.js'; +import { tShape } from 'lib/utils/validation-utils.js'; -import { validateAndConvert } from './media-utils.js'; +import { getMediaType, validateAndConvert } from './media-utils.js'; +import type { UploadInput } from '../creators/upload-creator.js'; import createUploads from '../creators/upload-creator.js'; import { deleteUpload } from '../deleters/upload-deleters.js'; import { @@ -22,6 +26,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'; const upload = multer(); const multerProcessor: Middleware<> = upload.array('multimedia'); @@ -89,6 +94,44 @@ return { results }; } +const uploadMediaMetadataInputValidator = tShape({ + filename: t.String, + width: t.Number, + height: t.Number, + blobHolder: t.String, + encryptionKey: t.String, + mimeType: t.String, + loop: t.maybe(t.Boolean), +}); + +async function uploadMediaMetadataResponder( + viewer: Viewer, + input: any, +): Promise { + const request: UploadMediaMetadataRequest = input; + await validateInput(viewer, uploadMediaMetadataInputValidator, input); + + const mediaType = getMediaType(request.mimeType); + if (!mediaType) { + throw new ServerError('invalid_parameters'); + } + + const { filename, blobHolder, encryptionKey, mimeType, width, height, loop } = + request; + const uploadInfo: UploadInput = { + name: filename, + mime: mimeType, + mediaType, + content: { storage: 'blob_service', blobHolder }, + encryptionKey, + dimensions: { width, height }, + loop: loop ?? false, + }; + + const [result] = await createUploads(viewer, [uploadInfo]); + return result; +} + async function uploadDownloadResponder( viewer: Viewer, req: $Request, @@ -168,4 +211,5 @@ multimediaUploadResponder, uploadDownloadResponder, uploadDeletionResponder, + uploadMediaMetadataResponder, }; 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 @@ -75,6 +75,15 @@ +id: string, }; +export type UploadMediaMetadataRequest = { + ...Dimensions, + +filename: string, + +blobHolder: string, + +encryptionKey: string, + +mimeType: string, + +loop?: boolean, +}; + export type FFmpegStatistics = { // seconds of video being processed per second +speed: number,