multer icon indicating copy to clipboard operation
multer copied to clipboard

File upload middleware does not work when I chain it with other middlewares. I get req.file = undefined

Open imhazard17 opened this issue 1 year ago • 5 comments
trafficstars

When I try to upload file without chaining the middlewares, the file upload works but when I chain it with other middlewares like input validation and authentication the file does not upload and I get req.file/req.files object as undefined.

Kindly help me to find what the issue is as I have been not able to find one yet.

I use postman to test the api and have set the correct body, authorization token and form data but still the error persists.

Github link of the project: https://github.com/imhazard17/user_mvp

Endpoint

// PUT /upl/upload
router.put('/upload', [userInputValidation, authentication, upload.single('file')], errForward(async (req, res) => {
    if (!req.file) {
        return res.status(404).json({ err: 'File not uploaded' })
    }

    return res.status(200).json({ file: req.file })
}))

Authentication middleware

function authentication(req, res, next) {
    if(!req.headers.authorization) {
        return res.status(411).json({
            err: 'Could not find auth token'
        })
    }

    const authToken = req.headers.authorization.split(' ')[1]

    let jwtVerifyRes
    
    try {
        jwtVerifyRes = jwt.verify(authToken, process.env.JWT_SECRET)
    } catch(e) {
        return res.status(403).json({
            err: 'Could not authenticate user'
        })
    } finally {
        req.locals = {}
        req.locals.userId = parseInt(jwtVerifyRes)
        next()
    }
}

Input validation middleware

function userInputValidation(req, res, next) {
    const schema = z.object({
        username: z.string().min(5).max(30)
        password: z.string().min(8).max(40),
        firstName: z.string().max(30).optional(),
        lastName: z.string().max(30).optional(),
    })

    try {
        schema.parse(req.body)
    } catch(e) {
        return res.status(411).json({
            err: 'Wrong inputs recieved'
        })
    } finally {
        next()
    }
}

imhazard17 avatar Mar 23 '24 13:03 imhazard17

Weird. Do you see that error when you're authorized and the input is valid? Meaning it's gotten successfully through the previous middleware?

I had another observation, I see the code is responding with a 411, which is Length Required. I presume it should be 401.

joeyguerra avatar Mar 30 '24 17:03 joeyguerra

I'd try to remove errForward middleware since the last middleware is synchronous - for ensuring the req context is not lost / overridden

Doc999tor avatar Apr 02 '24 00:04 Doc999tor

In case it helps, I encountered similar after adding express-openapi-validator to an endpoint expecting a single file. req.file was undefined but the uploaded file was still referenced in req.files[] as a single entry.

mattyod avatar Apr 30 '24 11:04 mattyod

In case it helps, I encountered similar after adding express-openapi-validator to an endpoint expecting a single file. req.file was undefined but the uploaded file was still referenced in req.files[] as a single entry.

I have the same issue in nestjs.

shellking4 avatar Oct 11 '24 16:10 shellking4