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 + @apidevtools/json-schema-ref-parser leads to an error in 5.2.0 #939

Open EvgenijHenning opened 4 months ago

EvgenijHenning commented 4 months ago

Describe the bug Since 5.2.0 I'm getting an error with the express-openapi-validator. With the previous 5.1.6 everything was finde. After some digging I could narrow it down to the json-schema-ref-parser.

While the initial loading is fine the validator throws exceptions on any endpoint call. The stack looks like:

ReferenceError: location is not defined
    at Object.cwd (/app/node_modules/@apidevtools/json-schema-ref-parser/dist/lib/util/url.js:71:9)
    at $RefParser.parse (/app/node_modules/@apidevtools/json-schema-ref-parser/dist/lib/index.js:101:37)
    at $RefParser.resolve (/app/node_modules/@apidevtools/json-schema-ref-parser/dist/lib/index.js:145:24)
    at $RefParser.bundle (/app/node_modules/@apidevtools/json-schema-ref-parser/dist/lib/index.js:165:24)
    at Object.bundle (/app/node_modules/@apidevtools/json-schema-ref-parser/dist/lib/index.js:160:32)
    at OpenAPIFramework.loadSpec (/app/node_modules/express-openapi-validator/dist/framework/index.js:62:34)
    at OpenAPIFramework.initialize (/app/node_modules/express-openapi-validator/dist/framework/index.js:16:35)
    at OpenApiSpecLoader.discoverRoutes (/app/node_modules/express-openapi-validator/dist/framework/openapi.spec.loader.js:29:60)
    at OpenApiSpecLoader.load (/app/node_modules/express-openapi-validator/dist/framework/openapi.spec.loader.js:21:21)
    at Module.openapiValidator (/app/node_modules/express-openapi-validator/dist/index.js:31:8)

To Reproduce I'll try to setup a repo for testing.

Actual behavior Starting up the server is fine but as soon as you call a route the exception is thrown.

Expected behavior The bug is only in 5.2.0 and going back to 5.1.6 resolves the issue.

Examples and context This is how I load the openapi.yaml file in

...
  const apiSpec = process.cwd() + '/openapi.yaml'
  const apiConfig = YAML.load(apiSpec)
...

  connector(operations, apiConfig, { apiSeparator: '/' })(app)
vganzin commented 3 weeks ago

@EvgenijHenning , hi! Have you solved this problem?

cdimascio commented 3 weeks ago

Can you provide a canonical version of your api spec that can be used to reproduce this issue.

vganzin commented 2 weeks ago

@cdimascio

function customResolver(handlersPath, route, apiDoc) {
    if (isMemberOfFakeHandler(route)) {
        return fakeHandler;
    }
    return OpenApiValidator.resolvers.defaultResolver(handlersPath, route, apiDoc);
}
const controllers = path.join(__dirname, 'api/controllers');

app.use(OpenApiValidator.middleware({
        apiSpec: swaggerDoc,
        operationHandlers: {
            basePath: controllers,
            resolver: customResolver,
        },
        validateRequests: {
            allowUnknownQueryParameters: true,
            coerceTypes: false
        },
        validateResponses: false,
        ignorePaths: ignorePaths,
        fileUploader: false
    }));

openapi.yaml

  /activate:
    post:
      operationId: activate
      x-eov-operation-handler: session
      x-eov-operation-id: activate
      summary: Activate channels
      tags:
        - Session
      description: Test Description
      requestBody:
        content:
          application/json:
            schema:
              required:
                - data
                ..................................

src/api/controllers/session.ts

 ....
const sessionController = {
  activate: activate
};
export = sessionController;

Its work in 5.1.6, but after 5.2.0 I have an error "location is not defined"

EvgenijHenning commented 2 weeks ago

@EvgenijHenning , hi! Have you solved this problem?

@vganzin I didn't. I rolled back to the old version and since then I had no time to look further into it.

Thanks for providing an example to reproduce the error.

vganzin commented 1 week ago

@cdimascio Problem in const controllers = path.join(__dirname, 'api/controllers'); operationHandlers: {basePath: controllers}

my tree -app.js -api --controllers ---session.js

in session.js const sessionController = { activate: activate }; module.exports = sessionController;

full path in my docker container "opt/production/application/app.js