fix: parse multipart uploads for shop-chat files and chat-room images
Same root cause as the shop logo fix: these two routes still expected req.files.<field> (the removed express-form-data pattern) with no multer middleware in front of them, so: - POST /shop-chat/:shopId/messages/file always rejected with "فایل الزامی است" even when a valid image/video was sent. - POST /chat-rooms room creation silently dropped room_image, and would lose all text fields (title, visibility, ...) whenever the request was multipart (i.e. whenever an image was attached). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -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 })
|
||||
|
||||
@@ -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') {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user