From f8e77ad01277b629c8b581e3ed8b4b72dc35605c Mon Sep 17 00:00:00 2001 From: Simon Backx Date: Thu, 16 Feb 2023 11:49:37 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fixed=20uploading=20images=20wit?= =?UTF-8?q?h=20custom=20storage=20adapters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes https://github.com/TryGhost/Ghost/issues/16278 `urlToPath` is not a method that is defined on the StorageBase, and thus is not implemented on any custom storage adapter. We need this method to prevent uploading a file in two different directories. Currently this is an edge case: - If you upload a file at midnight between a month shift, it is possible that we upload one file at `/2023/02/file.png` and the original at `/2023/03/file_o.png` - To make sure we upload the second at the same directory, we need the `urlToPath` implementation. The save method sadly only returns the URL, which could be different than the stored file path, so we cannot use that return value. This fix only uses `urlToPath` if available, to prevent above issue. --- .../core/core/server/api/endpoints/images.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/ghost/core/core/server/api/endpoints/images.js b/ghost/core/core/server/api/endpoints/images.js index e303776119..5ee97037d3 100644 --- a/ghost/core/core/server/api/endpoints/images.js +++ b/ghost/core/core/server/api/endpoints/images.js @@ -37,13 +37,20 @@ module.exports = { ...frame.file, path: out }); - const processedImagePath = store.urlToPath(processedImageUrl); - // Get the path and name of the processed image - // We want to store the original image on the same name + _o - // So we need to wait for the first store to finish before generating the name of the original image - const processedImageName = path.basename(processedImagePath); - const processedImageDir = path.dirname(processedImagePath); + let processedImageName = path.basename(processedImageUrl); + let processedImageDir = undefined; + + if (store.urlToPath) { + // Currently urlToPath is not part of StorageBase, so not all storage provider have implemented it + const processedImagePath = store.urlToPath(processedImageUrl); + + // Get the path and name of the processed image + // We want to store the original image on the same name + _o + // So we need to wait for the first store to finish before generating the name of the original image + processedImageName = path.basename(processedImagePath); + processedImageDir = path.dirname(processedImagePath); + } // Store the original image await store.save({