diff --git a/changelog.md b/changelog.md index fcf721b..06c42e9 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,11 @@ # graphql-upload changelog +## Next + +### Patch + +- Handle invalid object paths in `map` multipart field entries, fixing [#154](https://github.com/jaydenseric/graphql-upload/issues/154). + ## 8.0.6 ### Patch diff --git a/src/processRequest.mjs b/src/processRequest.mjs index 198ae26..cdfb688 100644 --- a/src/processRequest.mjs +++ b/src/processRequest.mjs @@ -271,7 +271,16 @@ export const processRequest = ( ) ) - operationsPath.set(path, map.get(fieldName).promise) + try { + operationsPath.set(path, map.get(fieldName).promise) + } catch (error) { + return exit( + createError( + 400, + `Invalid object path for the ‘map’ multipart field entry key ‘${fieldName}’ array index ‘${index}’ value ‘${path}’ (${SPEC_URL}).` + ) + ) + } } } diff --git a/src/test.mjs b/src/test.mjs index d5cc660..d7250e0 100644 --- a/src/test.mjs +++ b/src/test.mjs @@ -537,6 +537,53 @@ t.test('Invalid ‘map’ entry array item type.', async t => { }) }) +t.test('Invalid ‘map’ entry object path.', async t => { + const sendRequest = async (t, port) => { + const body = new FormData() + + body.append('operations', '{ "variables": "" }') + body.append('map', '{ "1": ["variables.file"] }') + body.append('1', 'a', { filename: 'a.txt' }) + + const { status } = await fetch(`http://localhost:${port}`, { + method: 'POST', + body + }) + + t.equal(status, 400, 'Response status.') + } + + await t.test('Koa middleware.', async t => { + t.plan(2) + + const app = new Koa() + .on('error', error => + t.matchSnapshot(snapshotError(error), 'Middleware throws.') + ) + .use(graphqlUploadKoa()) + + const port = await startServer(t, app) + + await sendRequest(t, port) + }) + + await t.test('Express middleware.', async t => { + t.plan(2) + + const app = express() + .use(graphqlUploadExpress()) + .use((error, request, response, next) => { + if (response.headersSent) return next(error) + t.matchSnapshot(snapshotError(error), 'Middleware throws.') + response.send() + }) + + const port = await startServer(t, app) + + await sendRequest(t, port) + }) +}) + t.test('Handles unconsumed uploads.', async t => { const sendRequest = async port => { const body = new FormData() diff --git a/tap-snapshots/lib-test-TAP.test.js b/tap-snapshots/lib-test-TAP.test.js index e391b1d..6eb5302 100644 --- a/tap-snapshots/lib-test-TAP.test.js +++ b/tap-snapshots/lib-test-TAP.test.js @@ -347,6 +347,26 @@ exports[`lib/test TAP Invalid ‘map’ entry array item type. Koa middleware. > } ` +exports[`lib/test TAP Invalid ‘map’ entry object path. Express middleware. > Middleware throws. 1`] = ` +{ + "name": "BadRequestError", + "message": "Invalid object path for the ‘map’ multipart field entry key ‘1’ array index ‘0’ value ‘variables.file’ (https://github.com/jaydenseric/graphql-multipart-request-spec).", + "status": 400, + "statusCode": 400, + "expose": true +} +` + +exports[`lib/test TAP Invalid ‘map’ entry object path. Koa middleware. > Middleware throws. 1`] = ` +{ + "name": "BadRequestError", + "message": "Invalid object path for the ‘map’ multipart field entry key ‘1’ array index ‘0’ value ‘variables.file’ (https://github.com/jaydenseric/graphql-multipart-request-spec).", + "status": 400, + "statusCode": 400, + "expose": true +} +` + exports[`lib/test TAP Invalid ‘map’ entry type. Express middleware. > Middleware throws. 1`] = ` { "name": "BadRequestError",