diff --git a/controllers/application/chatRooms/chatRoomController.js b/controllers/application/chatRooms/chatRoomController.js index 56a7e2f..c321b8e 100644 --- a/controllers/application/chatRooms/chatRoomController.js +++ b/controllers/application/chatRooms/chatRoomController.js @@ -225,14 +225,14 @@ const createRoom = async (req, res, next) => { } let imagePath = null - const imageFile = req.files?.room_image + const imageFile = req.file if (imageFile) { const uploadDir = path.join(__dirname, '../../../storage/chat-rooms') if (!fs.existsSync(uploadDir)) { fs.mkdirSync(uploadDir, { recursive: true }) } - // اسمِ فایل هیچ‌وقت مستقیم از ورودیِ کاربر (imageFile.name) گرفته نمی‌شه — فقط پسوندش - const uniqueFileName = `${Date.now()}-${crypto.randomUUID()}${path.extname(imageFile.name || '')}` + // اسمِ فایل هیچ‌وقت مستقیم از ورودیِ کاربر (imageFile.originalname) گرفته نمی‌شه — فقط پسوندش + const uniqueFileName = `${Date.now()}-${crypto.randomUUID()}${path.extname(imageFile.originalname || '')}` const filePath = path.join(uploadDir, uniqueFileName) await fs.move(imageFile.path, filePath) await optimizeImageFile(filePath, { maxDimension: 800 }) diff --git a/controllers/application/shop-chat/shopChatController.js b/controllers/application/shop-chat/shopChatController.js index 6287d02..09889d7 100644 --- a/controllers/application/shop-chat/shopChatController.js +++ b/controllers/application/shop-chat/shopChatController.js @@ -238,7 +238,7 @@ const sendShopChatFileMessage = async (req, res, next) => { const { shop, isOwner, buyerId } = ctx const { content, fileType } = req.body - const file = req.files?.file + const file = req.file if (!file) return chatError(res, 422, 'فایل الزامی است') if (!['image', 'video'].includes(fileType)) { @@ -250,8 +250,8 @@ const sendShopChatFileMessage = async (req, res, next) => { const uploadDir = path.join(__dirname, '../../../storage/shop-chat') fs.ensureDirSync(uploadDir) - // اسمِ فایل هیچ‌وقت مستقیم از ورودیِ کاربر (file.name) گرفته نمی‌شه — فقط پسوندش - const uniqueFileName = `${Date.now()}-${crypto.randomUUID()}${path.extname(file.name || '')}` + // اسمِ فایل هیچ‌وقت مستقیم از ورودیِ کاربر (file.originalname) گرفته نمی‌شه — فقط پسوندش + const uniqueFileName = `${Date.now()}-${crypto.randomUUID()}${path.extname(file.originalname || '')}` const filePath = path.join(uploadDir, uniqueFileName) await fs.move(file.path, filePath, { overwrite: true }) if (fileType === 'image') { diff --git a/routes/application/chat-rooms/index.js b/routes/application/chat-rooms/index.js index 4cf8c6d..aaa58ea 100644 --- a/routes/application/chat-rooms/index.js +++ b/routes/application/chat-rooms/index.js @@ -36,8 +36,25 @@ const roomMessageUpload = multer({ limits: { fileSize: 200 * 1024 * 1024 } }).single('file') +// همون باگ: createRoom منتظرِ req.files.room_image بود ولی این روت هیچ parserِ +// multipart نداشت — پس ساختِ اتاق با عکس همیشه شکست می‌خورد (یا حتی بدونِ عکس، +// اگه کلاینت همون درخواستِ multipart رو بدونِ فایل هم بفرسته، عنوانِ اتاق هم گم می‌شد) +const roomImageTmpDir = '/tmp/modstagram-uploads' +if (!fs.existsSync(roomImageTmpDir)) { + fs.mkdirSync(roomImageTmpDir, { recursive: true }) +} +const roomImageUpload = multer({ + storage: multer.diskStorage({ + destination: (req, file, cb) => cb(null, roomImageTmpDir), + filename: (req, file, cb) => { + cb(null, `${Date.now()}-${crypto.randomUUID()}${path.extname(file.originalname || '')}`) + } + }), + limits: { fileSize: 20 * 1024 * 1024 } +}).single('room_image') + router.get('/', listRooms) -router.post('/', createRoom) +router.post('/', roomImageUpload, createRoom) router.get('/:roomId', getRoomDetail) router.post('/:roomId/join', joinRoom) router.post('/:roomId/members', addRoomMembers) diff --git a/routes/application/shop-chat/index.js b/routes/application/shop-chat/index.js index 74c84f3..0a52639 100644 --- a/routes/application/shop-chat/index.js +++ b/routes/application/shop-chat/index.js @@ -1,4 +1,8 @@ const express = require('express') +const multer = require('multer') +const fs = require('fs') +const path = require('path') +const crypto = require('crypto') const blockCheck = require('../../../middlewares/blockCheck') const { getMyShopChats, @@ -9,9 +13,26 @@ const { const router = express.Router() +// همون دلیلِ shops/:id/logo: این روت بدونِ parserِ جایگزینِ express-form-data +// مونده بود، پس req.files همیشه undefined بود و ارسالِ عکس/ویدیو توی چتِ +// فروشگاه همیشه با «فایل الزامی است» رد می‌شد +const shopChatTmpDir = '/tmp/modstagram-uploads' +if (!fs.existsSync(shopChatTmpDir)) { + fs.mkdirSync(shopChatTmpDir, { recursive: true }) +} +const shopChatFileUpload = multer({ + storage: multer.diskStorage({ + destination: (req, file, cb) => cb(null, shopChatTmpDir), + filename: (req, file, cb) => { + cb(null, `${Date.now()}-${crypto.randomUUID()}${path.extname(file.originalname || '')}`) + } + }), + limits: { fileSize: 100 * 1024 * 1024 } +}).single('file') + router.get('/mine', [blockCheck], getMyShopChats) router.get('/:shopId/messages', [blockCheck], getShopChatMessages) router.post('/:shopId/messages', [blockCheck], sendShopChatMessage) -router.post('/:shopId/messages/file', [blockCheck], sendShopChatFileMessage) +router.post('/:shopId/messages/file', [blockCheck], shopChatFileUpload, sendShopChatFileMessage) module.exports = router