From 67356dec769b251c272ff48a5d1d8c411942febc Mon Sep 17 00:00:00 2001 From: Melsy Huamani Date: Fri, 26 Jun 2026 15:37:59 -0500 Subject: [PATCH] fix: support apiKey securitySchemes --- CHANGELOG.md | 7 ++ index.js | 2 +- package-lock.json | 4 +- package.json | 2 +- seeds/parserInitialGoodOpenApi3.json | 2 +- .../authorizationDefinition.js} | 16 ++-- test/parser-authorization-definition.js | 84 +++++++++++++++++++ 7 files changed, 107 insertions(+), 10 deletions(-) rename src/parser/{openapiAuthorizationDefinition.js => openapi3/authorizationDefinition.js} (91%) create mode 100644 test/parser-authorization-definition.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ace168..b7fdff4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [2.4.1-beta-1] - 2026-06-26 + +### Fixed +- Fix crash when `securitySchemes` contains `type: apiKey` or other non-OAuth2 schemes. + + ## [2.4.0] - 2026-05-07 ### Added diff --git a/index.js b/index.js index a378f2a..0487c7d 100644 --- a/index.js +++ b/index.js @@ -232,7 +232,7 @@ _.forEach(environments, function (element) { if ( element.custom_authorizations_file ) { require('./src/parser/authorizationRequests.js')(endpointsStage,element.custom_authorizations_file) } else if(global.definition.components.securitySchemes){ - let securityDefinition = require('./src/parser/openapiAuthorizationDefinition.js')(global.definition.components.securitySchemes) + let securityDefinition = require('./src/parser/openapi3/authorizationDefinition.js')(global.definition.components.securitySchemes) if(securityDefinition){ require('./src/parser/authorizationRequests.js')(endpointsStage,null,securityDefinition) } diff --git a/package-lock.json b/package-lock.json index 4cd3e68..e8dffa3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "openapi2postman", - "version": "2.4.0", + "version": "2.4.1-beta-1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "openapi2postman", - "version": "2.4.0", + "version": "2.4.1-beta-1", "license": "ISC", "dependencies": { "js-yaml": "^4.1.0", diff --git a/package.json b/package.json index 1ccfcf3..0b05d30 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openapi2postman", - "version": "2.4.0", + "version": "2.4.1-beta-1", "description": "openapi2postman", "bin": { "o2p": "index.js" diff --git a/seeds/parserInitialGoodOpenApi3.json b/seeds/parserInitialGoodOpenApi3.json index 6e46152..999350d 100644 --- a/seeds/parserInitialGoodOpenApi3.json +++ b/seeds/parserInitialGoodOpenApi3.json @@ -9,7 +9,7 @@ }, "servers":[ { - "url":"http://petstore.swagger.io/v1" + "url":"https://petstore.swagger.io/v1" } ], "paths":{ diff --git a/src/parser/openapiAuthorizationDefinition.js b/src/parser/openapi3/authorizationDefinition.js similarity index 91% rename from src/parser/openapiAuthorizationDefinition.js rename to src/parser/openapi3/authorizationDefinition.js index 3276ccb..4302966 100644 --- a/src/parser/openapiAuthorizationDefinition.js +++ b/src/parser/openapi3/authorizationDefinition.js @@ -10,13 +10,18 @@ module.exports = function() { return function get(oAuthDefinition){ let definition + let definitionKey for (const i in oAuthDefinition) { - definition = oAuthDefinition[i]; + if (oAuthDefinition[i]?.type === 'oauth2') { + definition = oAuthDefinition[i] + definitionKey = i + break + } } - const data = parseUrl(definition.flows) - if (!data) return null - const authKey = _.keys(globalThis.definition.security[0])[0] - return generateDefinition(data,authKey) + if (!definition) return null + const data = parseUrl(definition.flows) + if (!data) return null + return generateDefinition(data, definitionKey) } function generateDefinition(data,auth){ @@ -90,6 +95,7 @@ module.exports = function() { } function parseUrl(flows) { + if (!flows) return null let targetFlow = null for (const flowName of FLOW_PRIORITY) { if (flows[flowName]?.tokenUrl) { diff --git a/test/parser-authorization-definition.js b/test/parser-authorization-definition.js new file mode 100644 index 0000000..3fc520e --- /dev/null +++ b/test/parser-authorization-definition.js @@ -0,0 +1,84 @@ +/** Part of APIAddicts. See LICENSE file or full copyright and licensing details. Supported by Madrid Digital and CloudAPPi **/ + +const assert = require('node:assert'); +const get = require('../src/parser/openapi3/authorizationDefinition.js'); + +describe('parser-authorization-definition', () => { + + it('null apiKey only oa3', () => { + globalThis.definition = { security: [{ ApiKeyAuth: [] }] }; + const result = get({ ApiKeyAuth: { type: 'apiKey', in: 'header', name: 'X-API-Key' } }); + assert.strictEqual(result, null); + }); + + it('null http only oa3', () => { + globalThis.definition = { security: [{ BasicAuth: [] }] }; + const result = get({ BasicAuth: { type: 'http', scheme: 'basic' } }); + assert.strictEqual(result, null); + }); + + it('null empty schemes oa3', () => { + globalThis.definition = { security: [] }; + const result = get({}); + assert.strictEqual(result, null); + }); + + it('oauth2 definition apiKey first oa3', () => { + globalThis.definition = { security: [{ OAuth2: ['read'] }] }; + const result = get({ + ApiKeyAuth: { type: 'apiKey', in: 'header', name: 'X-API-Key' }, + OAuth2: { + type: 'oauth2', + flows: { + clientCredentials: { tokenUrl: 'https://auth.example.com/token', scopes: {} } + } + } + }); + assert.ok(result !== null); + assert.ok(result.item[0].name.includes('OAuth2')); + }); + + it('oauth2 definition oauth2 first oa3', () => { + globalThis.definition = { security: [{ OAuth2: ['read'] }] }; + const result = get({ + OAuth2: { + type: 'oauth2', + flows: { + clientCredentials: { tokenUrl: 'https://auth.example.com/token', scopes: {} } + } + }, + ApiKeyAuth: { type: 'apiKey', in: 'header', name: 'X-API-Key' } + }); + assert.ok(result !== null); + assert.ok(result.item[0].name.includes('OAuth2')); + }); + + it('oauth2 definition no global security oa3', () => { + globalThis.definition = { security: undefined }; + const result = get({ + OAuth2: { + type: 'oauth2', + flows: { + password: { tokenUrl: 'https://auth.example.com/token', scopes: {} } + } + } + }); + assert.ok(result !== null); + assert.ok(result.item[0].name.includes('OAuth2')); + }); + + it('oauth2 definition only oauth2 oa3', () => { + globalThis.definition = { security: [{ MyOAuth: [] }] }; + const result = get({ + MyOAuth: { + type: 'oauth2', + flows: { + password: { tokenUrl: 'https://auth.example.com/token', scopes: {} } + } + } + }); + assert.ok(result !== null); + assert.ok(result.item[0].name.includes('MyOAuth')); + }); + +});