cdimascio / express-openapi-validator

🦋 Auto-validates api requests, responses, and securities using ExpressJS and an OpenAPI 3.x specification
MIT License
920 stars 211 forks source link

`express-openapi-validator` does not support `explode: false` for query parameters #917

Closed Gituar closed 2 months ago

Gituar commented 6 months ago

Describe the bug The express-openapi-validator library does not properly support query parameters with explode: false as specified in the OpenAPI 3.0.3 specification. This causes validation errors for parameters that should allow reserved characters or have specified patterns and minimum lengths on the array items.

To Reproduce Steps to reproduce the behavior:

  1. Define an OpenAPI specification with an array query parameter that has explode: false and additional constraints such as pattern and minLength on the items.
  2. Use express-openapi-validator to validate a request against this specification.
  3. Make a request with the query parameter value test=categoryId%3AIN%3A%5B1%2C2%2C3%2C4%2C5%5D,itemId%3AEQ%3A2 containing reserved characters and ensuring the values match the defined pattern and length requirements.

Actual behavior Validation errors occur for the parameter:

Expected behavior The library should properly handle array query parameters with explode: false:

Examples and context Example OpenAPI specification snippet:

parameters:
  - name: test
    in: query
    explode: false
    schema:
      type: array
      items:
        type: string
        pattern: '^[a-zA-Z0-9]+:(EQ|IN)(:.+)?$'
        minLength: 5
        example: 'itemId:EQ:2'
    example: 'categoryId:IN:[1,2,3,4,5],itemId:EQ:2'

If allowReserved: true is set on the array in the OpenAPI specification, the must be URL encoded error is bypassed. However, the must match pattern error persists even though the parameter value is URL encoded and should match the pattern when decoded. It seems that the express-openapi-validator URL decodes the parameter value too soon, leading to this mismatch.

Example stack trace:

Bad Request: Parameter 'test' must be url encoded. Its value may not contain reserved characters.
    at RequestParameterMutator.validateReservedCharacters (/node_modules/express-openapi-validator/dist/middlewares/parsers/req.parameter.mutator.js:268:23)
    at /node_modules/express-openapi-validator/dist/middlewares/parsers/req.parameter.mutator.js:49:22
    at Array.forEach (<anonymous>)
    at RequestParameterMutator.modifyRequest (/node_modules/express-openapi-validator/dist/middlewares/parsers/req.parameter.mutator.js:41:28)
    at Object.GET-/test/api/v1/test-not_provided (/node_modules/express-openapi-validator/dist/middlewares/openapi.request.validator.js:87:21)
    at RequestValidator.validate (/node_modules/express-openapi-validator/dist/middlewares/openapi.request.validator.js:44:41)
    at /node_modules/express-openapi-validator/dist/openapi.validator.js:233:53
    at /node_modules/express-openapi-validator/dist/openapi.validator.js:165:28

OpenAPI 3.0 introduced support for style and explode keywords for parameter serialization, including arrays and objects in query parameters​ (Parameter Serialization)​​ (A Guide to What’s New in OpenAPI 3.0)​. The default serialization method for query parameters is style: form and explode: true. Using explode: false changes the serialization format, which should be properly handled by the validator (Describing Parameters)​​ (OpenAPI Specification v3.0.3)​.

dusanmi commented 5 months ago

Proposed fix https://github.com/cdimascio/express-openapi-validator/pull/935