From d4c5e294a02062e9ea055089ffcc3137fd3a1dcd Mon Sep 17 00:00:00 2001 From: vincentbpro <89356961+vincentbpro@users.noreply.github.com> Date: Wed, 6 Apr 2022 11:50:00 +0200 Subject: [PATCH] feat(logo-customization): parsing and validating image dimensions --- .../core/admin/server/controllers/admin.js | 6 +- .../admin/server/services/project-settings.js | 56 ++++++++++++------- .../server/validation/project-settings.js | 21 +++++-- 3 files changed, 59 insertions(+), 24 deletions(-) diff --git a/packages/core/admin/server/controllers/admin.js b/packages/core/admin/server/controllers/admin.js index b7c24a6821..9f159558ca 100644 --- a/packages/core/admin/server/controllers/admin.js +++ b/packages/core/admin/server/controllers/admin.js @@ -11,6 +11,7 @@ const ee = require('@strapi/strapi/lib/utils/ee'); const { validateUpdateProjectSettings, validateUpdateProjectSettingsFiles, + validateUpdateProjectSettingsImagesDimensions, } = require('../validation/project-settings'); const { getService } = require('../utils'); @@ -48,6 +49,8 @@ module.exports = { }, async updateProjectSettings(ctx) { + const projectSettingsService = getService('project-settings'); + const { request: { files, body }, } = ctx; @@ -55,7 +58,8 @@ module.exports = { await validateUpdateProjectSettings(body); await validateUpdateProjectSettingsFiles(files); - const projectSettingsService = getService('project-settings'); + const formatedFiles = await projectSettingsService.getFormatedFilesData(files); + await validateUpdateProjectSettingsImagesDimensions(formatedFiles); const uploadedFiles = await projectSettingsService.uploadFiles(files); const updatedProjectSettings = await projectSettingsService.updateProjectSettings( diff --git a/packages/core/admin/server/services/project-settings.js b/packages/core/admin/server/services/project-settings.js index fd25f028b4..4c74877444 100644 --- a/packages/core/admin/server/services/project-settings.js +++ b/packages/core/admin/server/services/project-settings.js @@ -1,28 +1,45 @@ 'use strict'; const fs = require('fs'); -const { transform } = require('lodash'); const PROJECT_SETTINGS_FILE_INPUTS = ['menuLogo']; -const getFormatedFileData = data => ({ - path: data.path, - ...strapi - .plugin('upload') - .service('upload') - .formatFileInfo({ - filename: data.name, - type: data.type, - size: data.size, - }), -}); +const getFormatedFilesData = async files => { + const formatedFilesData = {}; + + const results = PROJECT_SETTINGS_FILE_INPUTS.map(async inputName => { + if (!files[inputName]) { + return; + } + + formatedFilesData[inputName] = { + path: files[inputName].path, + + // Get file info + ...strapi + .plugin('upload') + .service('upload') + .formatFileInfo({ + filename: files[inputName].name, + type: files[inputName].type, + size: files[inputName].size, + }), + + // Get image file dimensions + ...(await strapi + .plugin('upload') + .service('image-manipulation') + .getDimensions({ getStream: () => fs.createReadStream(files[inputName].path) })), + }; + }); + + await Promise.all(results); + + return formatedFilesData; +}; const uploadFiles = async files => { - const formatedFilesData = transform(files, (result, value, key) => { - if (value) { - result[key] = getFormatedFileData(value); - } - }); + const formatedFilesData = getFormatedFilesData(files); Object.values(formatedFilesData).map(data => // Do not await to upload asynchronously @@ -59,8 +76,8 @@ const updateProjectSettings = async (body, uploadedFiles) => { newSettings[inputName] = { name: newSettings[inputName].name, url: 'test', - width: 0, - height: 0, + width: newSettings[inputName].width, + height: newSettings[inputName].height, }; } }); @@ -69,6 +86,7 @@ const updateProjectSettings = async (body, uploadedFiles) => { }; module.exports = { + getFormatedFilesData, uploadFiles, updateProjectSettings, }; diff --git a/packages/core/admin/server/validation/project-settings.js b/packages/core/admin/server/validation/project-settings.js index 2f7e12e030..a525bed005 100644 --- a/packages/core/admin/server/validation/project-settings.js +++ b/packages/core/admin/server/validation/project-settings.js @@ -2,8 +2,10 @@ const { yup, validateYupSchemaSync } = require('@strapi/utils'); -const MAX_LOGO_SIZE = 1024 * 1024; // 1Mo -const ALLOWED_LOGO_FILE_TYPES = ['image/jpeg', 'image/png', 'image/svg+xml']; +const MAX_IMAGE_WIDTH = 750; +const MAX_IMAGE_HEIGHT = MAX_IMAGE_WIDTH; +const MAX_IMAGE_FILE_SIZE = 1024 * 1024; // 1Mo +const ALLOWED_IMAGE_FILE_TYPES = ['image/jpeg', 'image/png', 'image/svg+xml']; const updateProjectSettings = yup .object({ @@ -15,13 +17,24 @@ const updateProjectSettingsFiles = yup .object({ menuLogo: yup.object({ name: yup.string(), - type: yup.string().oneOf(ALLOWED_LOGO_FILE_TYPES), - size: yup.number().max(MAX_LOGO_SIZE), + type: yup.string().oneOf(ALLOWED_IMAGE_FILE_TYPES), + size: yup.number().max(MAX_IMAGE_FILE_SIZE), }), }) .noUnknown(); +const updateProjectSettingsImagesDimensions = yup + .object({ + menuLogo: yup.object({ + width: yup.number().max(MAX_IMAGE_WIDTH), + height: yup.number().max(MAX_IMAGE_HEIGHT), + }), + }) + module.exports = { validateUpdateProjectSettings: validateYupSchemaSync(updateProjectSettings), validateUpdateProjectSettingsFiles: validateYupSchemaSync(updateProjectSettingsFiles), + validateUpdateProjectSettingsImagesDimensions: validateYupSchemaSync( + updateProjectSettingsImagesDimensions + ), };