swagger-express-middleware icon indicating copy to clipboard operation
swagger-express-middleware copied to clipboard

Parsing array in req.body fails for date-time values

Open Steffen911 opened this issue 6 years ago • 4 comments

What happened: My body contains an array of objects that contain date-time strings. When I try to parse a valid body with the parseRequest() middleware an exception is thrown saying Invalid type: object (expected string).

I assume that this is related to the validation that happens after parsing: https://github.com/APIDevTools/swagger-express-middleware/blob/master/lib/helpers/json-schema.js#L434

The date-time is converted into a Date object and, therefore, is not a string anymore. Hence, the second validation fails with the above statement.

What I expect to happen: The validation should succeed.

Example: spec:

parameters:
  - in: body
    name: body
    schema:
      type: array
      items:
        type: object
        properties:
          startDate:
            type: string
            format: date-time

body:

[{
  "startDate": "2018-03-23T04:11:21Z"
}]

Steffen911 avatar Jan 08 '19 15:01 Steffen911

You can reproduce this issue with the following test-case: https://github.com/Steffen911/swagger-express-middleware/commit/a6126a5f051c3e5def2626c10df59f7a87ad1c61

Steffen911 avatar Jan 09 '19 12:01 Steffen911

we are also hitting this issue, any ETA for fix?

mayankiitg avatar Oct 10 '19 18:10 mayankiitg

Any update or work arround for it?

clemens-smartparking avatar Jun 23 '20 03:06 clemens-smartparking

I debugged it a bit further. In lib/helpers/json-schema.js:

  if (schema.items.type === "string") {
    // Validate the array against the schema BEFORE parsing the items
    jsonValidate(schema, parsedValue, propPath);
  }

  // Parse the items in the array
  parseArrayItems(schema, parsedValue, propPath);

  if (schema.items.type !== "string") {
    // Validate the array against the schema AFTER parsing the items
    jsonValidate(schema, parsedValue, propPath);
  }

parseArrayItems transforms the string into a Date object and the next jsonValidate fails.

changing the block to:

if (schema.items.type === "string" || schema.items.type === "object") {
    // Validate the array against the schema BEFORE parsing the items
    jsonValidate(schema, parsedValue, propPath);
  }

  // Parse the items in the array
  parseArrayItems(schema, parsedValue, propPath);

  if (schema.items.type !== "string" && schema.items.type !== "object") {
    // Validate the array against the schema AFTER parsing the items
    jsonValidate(schema, parsedValue, propPath);
  }

makes all test pass...

@JamesMessinger could you give more info on why the jsonValidate is sometimes done BEFORE and sometimes AFTER?

clemens-smartparking avatar Jun 24 '20 03:06 clemens-smartparking