From 98fab68616c97458debda1f165b494ddd8b0b20f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Poullain?= Date: Wed, 8 Apr 2020 11:30:25 +0200 Subject: [PATCH] Fix multipart fields validation --- ...date-multipart-form-data-body.hook.spec.ts | 46 +++++++++++++------ .../validate-multipart-form-data-body.hook.ts | 8 +++- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/packages/storage/src/validate-multipart-form-data-body.hook.spec.ts b/packages/storage/src/validate-multipart-form-data-body.hook.spec.ts index 54f7acd041..fd1fbe1dc6 100644 --- a/packages/storage/src/validate-multipart-form-data-body.hook.spec.ts +++ b/packages/storage/src/validate-multipart-form-data-body.hook.spec.ts @@ -56,10 +56,7 @@ describe('ValidateMultipartFormDataBody', () => { const actual: { body: any } = { body: null }; const app = createAppWithHook({ fields: { - properties: { - name: { type: 'string' } - }, - type: 'object', + name: { type: 'string' } }, files: {} }, actual); @@ -67,6 +64,7 @@ describe('ValidateMultipartFormDataBody', () => { await request(app) .post('/') .field('name', 'hello') + .field('unexpectedName', 'world') .expect(200); deepStrictEqual(actual.body.fields, { @@ -114,13 +112,10 @@ describe('ValidateMultipartFormDataBody', () => { rmdirSync('uploaded'); }); - it('should return an HttpResponseBadRequest.', async () => { + it('should return an HttpResponseBadRequest (invalid values).', async () => { const app = createAppWithHook({ fields: { - properties: { - name: { type: 'boolean' } - }, - type: 'object', + name: { type: 'boolean' } }, files: {} }, { body: null }); @@ -144,13 +139,38 @@ describe('ValidateMultipartFormDataBody', () => { }); }); + it('should return an HttpResponseBadRequest (missing values).', async () => { + const app = createAppWithHook({ + fields: { + name: { type: 'string' }, + name2: { type: 'string' } + }, + files: {} + }, { body: null }); + + await request(app) + .post('/') + .field('name', 'hello') + .expect(400) + .expect({ + body: [ + { + dataPath: '', + keyword: 'required', + message: 'should have required property \'name2\'', + params: { + missingProperty: 'name2' + }, + schemaPath: '#/required', + } + ] + }); + }); + it('should not have uploaded the files.', async () => { const app = createAppWithHook({ fields: { - properties: { - name: { type: 'boolean' } - }, - type: 'object', + name: { type: 'boolean' } }, files: { foobar: { required: false, multiple: true, saveTo: 'images' }, diff --git a/packages/storage/src/validate-multipart-form-data-body.hook.ts b/packages/storage/src/validate-multipart-form-data-body.hook.ts index 8d89b2438f..f321fd88d9 100644 --- a/packages/storage/src/validate-multipart-form-data-body.hook.ts +++ b/packages/storage/src/validate-multipart-form-data-body.hook.ts @@ -158,7 +158,13 @@ const hook = (schema: MultipartFormDataSchema): HookDecorator => { // Validate the fields const ajv = getAjvInstance(); - if (schema.fields && !ajv.validate(schema.fields, fields)) { + const ajvSchema = { + additionalProperties: false, + properties: schema.fields, + required: Object.keys(schema.fields || {}), + type: 'object', + }; + if (schema.fields && !ajv.validate(ajvSchema, fields)) { await deleteUploadedFiles(); return new HttpResponseBadRequest({ body: ajv.errors }); }