diff --git a/keyserver/src/creators/upload-creator.js b/keyserver/src/creators/upload-creator.js --- a/keyserver/src/creators/upload-creator.js +++ b/keyserver/src/creators/upload-creator.js @@ -21,6 +21,7 @@ buffer: Buffer, dimensions: Dimensions, loop: boolean, + encryptionKey?: string, }; async function createUploads( viewer: Viewer, @@ -34,7 +35,7 @@ const uploadRows = uploadInfos.map(uploadInfo => { const id = ids.shift(); const secret = crypto.randomBytes(8).toString('hex'); - const { dimensions, mediaType, loop } = uploadInfo; + const { dimensions, mediaType, loop, encryptionKey } = uploadInfo; return { uploadResult: { id, @@ -52,7 +53,7 @@ uploadInfo.buffer, secret, Date.now(), - JSON.stringify({ ...dimensions, loop }), + JSON.stringify({ ...dimensions, loop, encryptionKey }), ], }; }); 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 @@ -8,6 +8,7 @@ serverTranscodableTypes, serverCanHandleTypes, readableFilename, + mediaConfig, } from 'lib/media/file-utils.js'; import { getImageProcessingPlan } from 'lib/media/image-utils.js'; import type { Dimensions } from 'lib/types/media-types.js'; @@ -29,13 +30,59 @@ }); } +type ValidateAndConvertInput = { + +initialBuffer: Buffer, + +initialName: string, + +inputDimensions: ?Dimensions, + +inputLoop: boolean, + +inputEncryptionKey: ?string, + +inputMimeType: ?string, + +size: number, // in bytes +}; async function validateAndConvert( - initialBuffer: Buffer, - initialName: string, - inputDimensions: ?Dimensions, - inputLoop: boolean, - size: number, // in bytes + input: ValidateAndConvertInput, ): Promise { + const { + initialBuffer, + initialName, + inputDimensions, + inputLoop, + inputEncryptionKey, + inputMimeType, + size, // in bytes + } = input; + + // we don't want to transcode encrypted files + if (inputEncryptionKey) { + invariant( + inputMimeType, + 'inputMimeType should be set in validateAndConvert for encrypted files', + ); + invariant( + inputDimensions, + 'inputDimensions should be set in validateAndConvert for encrypted files', + ); + + 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 { + name: initialName, + mime: inputMimeType, + mediaType, + buffer: initialBuffer, + dimensions: inputDimensions, + loop: inputLoop, + encryptionKey: inputEncryptionKey, + }; + } + const { mime, mediaType } = deepFileInfoFromData(initialBuffer); if (!mime || !mediaType) { return null; 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 @@ -70,13 +70,15 @@ const validationResults = await Promise.all( files.map(({ buffer, size, originalname }) => - validateAndConvert( - buffer, - overrideFilename ? overrideFilename : originalname, + validateAndConvert({ + initialBuffer: buffer, + initialName: overrideFilename ? overrideFilename : originalname, inputDimensions, inputLoop, + inputEncryptionKey, + inputMimeType, size, - ), + }), ), ); const uploadInfos = validationResults.filter(Boolean);