New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

openapi-enforcer

Package Overview
Dependencies
Maintainers
1
Versions
131
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

openapi-enforcer - npm Package Compare versions

Comparing version 1.14.2 to 1.14.3

test-resources/issue-118/openapi.yml

15

CHANGELOG.md

@@ -7,3 +7,18 @@ # Change Log

## 1.14.3
### Fixed
- **Reporting for Equivalent Paths**
A bug was identified that could incorrectly report the wrong paths when equivalent paths were identified.
## 1.14.2
### Fixed
- **Example Validation with One Of Schema**
There were several problems with validating examples against schemas with `oneOf`. This has been fixed.
## 1.14.1

@@ -10,0 +25,0 @@

2

package.json
{
"name": "openapi-enforcer",
"version": "1.14.2",
"version": "1.14.3",
"description": "Library for validating, parsing, and formatting data against open api schemas.",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -19,4 +19,5 @@ /**

const EnforcerRef = require('../enforcer-ref');
const util = require('../util')
const methods = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'];
const methods = util.methods()

@@ -23,0 +24,0 @@ module.exports = {

@@ -22,2 +22,3 @@ /**

const rxPathParam = /{([^}]+)}/;
const methods = util.methods()

@@ -28,4 +29,4 @@ module.exports = {

const pathParsers = {};
const pathEquivalencies = {};
const paramlessMap = {};
// const pathEquivalencies = {};
// const paramlessMap = {};

@@ -99,17 +100,17 @@ if (!data.options.disablePathNormalization) {

path.methods.forEach(method => {
equivalencyKey += method + equivalencyKey;
// path.methods.forEach(method => {
// equivalencyKey += method + equivalencyKey;
//
// if (!paramlessMap[equivalencyKey]) paramlessMap[equivalencyKey] = [];
// const paramless = paramlessMap[equivalencyKey];
//
// if (!pathEquivalencies[equivalencyKey]) pathEquivalencies[equivalencyKey] = [];
// if (pathEquivalencies[equivalencyKey].length === 0) pathEquivalencies[equivalencyKey].push(pathKey);
// if (!paramless.includes(paramlessStr)) {
// paramless.push(paramlessStr);
// } else {
// pathEquivalencies[equivalencyKey].push(pathKey);
// }
// });
if (!paramlessMap[equivalencyKey]) paramlessMap[equivalencyKey] = [];
const paramless = paramlessMap[equivalencyKey];
if (!pathEquivalencies[equivalencyKey]) pathEquivalencies[equivalencyKey] = [];
if (pathEquivalencies[equivalencyKey].length === 0) pathEquivalencies[equivalencyKey].push(pathKey);
if (!paramless.includes(paramlessStr)) {
paramless.push(paramlessStr);
} else {
pathEquivalencies[equivalencyKey].push(pathKey);
}
});
const rx = new RegExp('^' + rxStr + '$');

@@ -141,11 +142,69 @@

const equivalencyException = exception.nest('Equivalent paths are not allowed');
Object.keys(pathEquivalencies).forEach(key => {
const array = pathEquivalencies[key];
if (array.length > 1) {
const conflicts = equivalencyException.nest('Equivalent paths:');
array.forEach(err => conflicts.push(err));
// convert paths into signatures
const pathParamSymbol = Symbol('path parameter')
const pathKeySignatures = []
Object.keys(result).forEach((pathKey, index) => {
const rxPathParameter = /{([^}]+)}/g;
const pathSignature = []
let match
let offset = 0
// pathKey = util.edgeSlashes(pathKey, false, false);
while ((match = rxPathParameter.exec(pathKey))) {
const str = pathKey.substring(offset, match.index)
pathSignature.push(str)
pathSignature.push(pathParamSymbol)
offset = match.index + match[0].length
}
});
const str = pathKey.substring(offset)
pathSignature.push(str)
methods
.filter(method => result[pathKey].hasOwnProperty(method))
.forEach(method => {
pathKeySignatures.push({
key: pathKey,
method,
signature: [method].concat(pathSignature)
})
})
})
// find equivalent paths based on signatures
const pathEquivalencies = []
const alreadyMatchedPathEquivalencies = []
pathKeySignatures.forEach((top) => {
const duplicates = pathKeySignatures.filter((bottom) => {
const length = bottom.signature.length
if (top === bottom || top.signature.length !== length || alreadyMatchedPathEquivalencies.includes(bottom.key)) return false
for (let k = 0; k < length; k++) {
if (bottom.signature[k] !== top.signature[k]) return false
}
return true
})
if (duplicates.length > 0) {
duplicates.unshift(top)
duplicates.forEach(item => alreadyMatchedPathEquivalencies.push(item.key))
pathEquivalencies.push(duplicates)
}
})
// report path equivalencies
const equivalencyException = exception.nest('Equivalent paths are not allowed');
pathEquivalencies.forEach(matches => {
const conflicts = equivalencyException.nest('Equivalent paths:');
matches.forEach(item => conflicts.push(item.method.toUpperCase() + ' ' + item.key));
})
// report equivalent paths
// const equivalencyException = exception.nest('Equivalent paths are not allowed');
// Object.keys(pathEquivalencies).forEach(key => {
// const array = pathEquivalencies[key];
// if (array.length > 1) {
// const conflicts = equivalencyException.nest('Equivalent paths:');
// array.forEach(err => conflicts.push(err));
// }
// });
Object.keys(pathParsers).forEach(key => {

@@ -152,0 +211,0 @@ pathParsers[key].sort((a, b) => a.weight < b.weight ? -1 : 1);

@@ -50,2 +50,3 @@ /**

merge,
methods,
mostOf,

@@ -389,2 +390,6 @@ parseCookieString,

function methods () {
return ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'];
}
function mostOf (numberArray) {

@@ -391,0 +396,0 @@ const length = numberArray.length;

@@ -222,2 +222,13 @@ const expect = require('chai').expect;

describe('issue-118 - incorrectly identifies duplicate paths', () => {
it('will correctly identify duplicate paths', async () => {
const [ , err ] = await Enforcer(path.resolve(resourcesPath, 'issue-118/openapi.yml'), { fullResult: true });
expect(err).to.match(/Equivalent paths are not allowed/)
expect(err).to.match(/GET \/user\/{userId}/)
expect(err).to.match(/GET \/user\/{username}/)
})
})
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc