From 6e25e1a38a1cd094bbc0aa3df3af431d365bd687 Mon Sep 17 00:00:00 2001 From: payacom Date: Wed, 28 Oct 2026 16:46:04 +0330 Subject: [PATCH] fix(shops): parse multipart logo upload on PATCH /shops/:id/logo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit req.files.logo relied on an express-form-data style parser that was removed app-wide, so the route never had a multipart parser and every logo upload failed with "لطفاً لوگوی فروشگاه را انتخاب کنید" even though the client had already picked and sent an image. Add the same multer-based pattern already used for profile_image and shop-products image uploads. Co-Authored-By: Claude Sonnet 5 --- .../application/shops/shopController.js | 4 ++-- routes/application/shops/index.js | 22 ++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/controllers/application/shops/shopController.js b/controllers/application/shops/shopController.js index e33f017..e0b93da 100644 --- a/controllers/application/shops/shopController.js +++ b/controllers/application/shops/shopController.js @@ -281,7 +281,7 @@ const updateShopLogo = async (req, res, next) => { if (error === 'NOT_FOUND') return shopError(res, 404, 'فروشگاه یافت نشد') if (error === 'FORBIDDEN') return shopError(res, 403, 'شما مالک این فروشگاه نیستید') - const logo = req.files?.logo + const logo = req.file if (!logo) { return shopError(res, 422, 'لطفاً لوگوی فروشگاه را انتخاب کنید') } @@ -289,7 +289,7 @@ const updateShopLogo = async (req, res, next) => { const uploadDir = path.join(__dirname, '../../../storage/shops') fs.ensureDirSync(uploadDir) - const uniqueFileName = `${shop._id}-${Date.now()}${path.extname(logo.name)}` + const uniqueFileName = `${shop._id}-${Date.now()}${path.extname(logo.originalname || '')}` const filePath = path.join(uploadDir, uniqueFileName) await fs.move(logo.path, filePath, { overwrite: true }) await optimizeImageFile(filePath, { maxDimension: 800 }) diff --git a/routes/application/shops/index.js b/routes/application/shops/index.js index 186b100..ed47bf7 100644 --- a/routes/application/shops/index.js +++ b/routes/application/shops/index.js @@ -1,4 +1,7 @@ const express = require('express') +const multer = require('multer') +const fs = require('fs') +const path = require('path') const { createDraftShop, getMyShops, @@ -29,6 +32,23 @@ const requireSubUserPermission = require('../../../middlewares/requireSubUserPer const router = express.Router() +// req.files مثلِ قبلاً توسطِ express-form-data پر می‌شد؛ بعدِ حذفِ اون middleware +// (تداخل با multer توی posts/chat) این روت بدونِ parser جایگزین مونده بود — یعنی +// آپلودِ لوگوی فروشگاه همیشه با «لطفاً لوگو را انتخاب کنید» رد می‌شد +const shopLogoTmpDir = '/tmp/modstagram-uploads' +if (!fs.existsSync(shopLogoTmpDir)) { + fs.mkdirSync(shopLogoTmpDir, { recursive: true }) +} +const shopLogoUpload = multer({ + storage: multer.diskStorage({ + destination: (req, file, cb) => cb(null, shopLogoTmpDir), + filename: (req, file, cb) => { + cb(null, `${Date.now()}-${Math.round(Math.random() * 1e9)}${path.extname(file.originalname || '')}`) + } + }), + limits: { fileSize: 50 * 1024 * 1024 } +}).single('logo') + router.post('/draft', [blockCheck], requireSubUserPermission('create_shop'), createDraftShop) router.get('/mine', [blockCheck], getMyShops) router.get('/analytics', [blockCheck], getShopAnalytics) @@ -44,7 +64,7 @@ router.post('/favorites/toggle', [blockCheck], toggleFavorite) router.get('/public/:id', getShopPublic) router.get('/:id', [blockCheck], getShopById) router.patch('/:id/basic', [blockCheck], requireSubUserPermission('create_shop'), updateShopBasic) -router.patch('/:id/logo', [blockCheck], requireSubUserPermission('create_shop'), updateShopLogo) +router.patch('/:id/logo', [blockCheck], requireSubUserPermission('create_shop'), shopLogoUpload, updateShopLogo) router.patch('/:id/shipping', [blockCheck], requireSubUserPermission('create_shop'), updateShopShipping) router.patch('/:id/location', [blockCheck], requireSubUserPermission('create_shop'), updateShopLocation) router.patch('/:id/contact', [blockCheck], requireSubUserPermission('create_shop'), updateShopContact)