Socket
Socket
Sign inDemoInstall

fury-adapter-oas3-parser

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fury-adapter-oas3-parser - npm Package Compare versions

Comparing version 0.9.1 to 0.10.0

lib/parser/oas/parseLicenseObject.js

6

CHANGELOG.md
# Fury OAS3 Parser Changelog
## 0.10.0 (2019-12-06)
### Enhancements
- Added support for `info.license` (License Object).
## 0.9.1 (2019-08-08)

@@ -4,0 +10,0 @@

@@ -19,4 +19,16 @@ const State = require('./state.js');

}
oauthFlow(id, flow) {
return this.state.oauthFlow(id, flow);
}
registerScheme(id) {
return this.state.registerScheme(id);
}
hasScheme(id) {
return this.state.hasScheme(id);
}
}
module.exports = Context;

38

lib/parser/oas/parseComponentsObject.js

@@ -155,13 +155,43 @@ const R = require('ramda');

(object) => {
const parseResult = new namespace.elements.ParseResult([]);
const array = new namespace.elements.Array([]);
object.forEach((value, key) => {
const keyValue = key.toValue();
if (value) {
// eslint-disable-next-line no-param-reassign
value.meta.id = key.clone();
array.push(value);
if (value instanceof namespace.elements.AuthScheme) {
if (!context.registerScheme(keyValue)) {
parseResult.push(createWarning(namespace,
`'${keyValue}' security scheme is already defined`, key));
} else {
// eslint-disable-next-line no-param-reassign
value.id = key.clone();
array.push(value);
}
return;
}
// append oauth2 flow names
value.forEach((flow) => {
const flowSchemeName = `${keyValue} ${flow.grantTypeValue}`;
if (!context.oauthFlow(keyValue, flowSchemeName)) {
parseResult.push(createWarning(namespace,
`'${flowSchemeName}' security scheme can't be created from '${keyValue}' security scheme because it is already defined`, key));
} else {
// eslint-disable-next-line no-param-reassign
flow.id = flowSchemeName;
array.push(flow);
}
});
}
});
return array;
if (!array.isEmpty) {
parseResult.push(array);
}
return parseResult;
});

@@ -168,0 +198,0 @@

10

lib/parser/oas/parseInfoObject.js

@@ -8,3 +8,3 @@ const R = require('ramda');

const {
isObject, hasKey, isExtension,
isObject, hasKey, getValue, isExtension,
} = require('../../predicates');

@@ -15,6 +15,7 @@ const parseObject = require('../parseObject');

const pipeParseResult = require('../../pipeParseResult');
const parseLicenseObject = require('./parseLicenseObject');
const name = 'Info Object';
const requiredKeys = ['title', 'version'];
const unsupportedKeys = ['termsOfService', 'contact', 'license'];
const unsupportedKeys = ['termsOfService', 'contact'];

@@ -43,2 +44,3 @@ /**

[hasKey('description'), parseCopy(context, name, false)],
[hasKey('license'), R.compose(parseLicenseObject(context), getValue)],
[isUnsupportedKey, createUnsupportedMemberWarning(namespace, name)],

@@ -66,2 +68,6 @@

if (info.get('license')) {
api.links.push(info.get('license'));
}
return api;

@@ -68,0 +74,0 @@ });

@@ -43,7 +43,21 @@ const R = require('ramda');

const parseUrl = pipeParseResult(namespace,
parseString(context, name, false),
(url) => {
const transition = new namespace.elements.Transition();
transition.href = url.value.clone();
transition.relation = url.key.clone();
// remove 'Url' from key
transition.relation.content = transition.relation.toValue().slice(0, -3);
return transition;
});
const parseMember = R.cond([
[hasKey('scopes'), R.compose(parseScopes, getValue)],
[hasKey('refreshUrl'), parseString(context, name, false)],
[hasKey('authorizationUrl'), parseString(context, name, false)],
[hasKey('tokenUrl'), parseString(context, name, false)],
[hasKey('refreshUrl'), parseUrl],
[hasKey('authorizationUrl'), parseUrl],
[hasKey('tokenUrl'), parseUrl],

@@ -50,0 +64,0 @@ // FIXME Support exposing extensions into parse result

@@ -75,2 +75,6 @@ const R = require('ramda');

R.filter(R.is(namespace.elements.Transition), member.value).forEach((item) => {
authScheme.push(item);
});
return authScheme;

@@ -77,0 +81,0 @@ }));

@@ -18,6 +18,7 @@ /* eslint-disable no-underscore-dangle */

const parseComponentsObject = require('./parseComponentsObject');
const parseSecurityRequirementsArray = require('./parseSecurityRequirementsArray');
const name = 'OpenAPI Object';
const requiredKeys = ['openapi', 'info', 'paths'];
const unsupportedKeys = ['servers', 'security', 'tags', 'externalDocs'];
const unsupportedKeys = ['servers', 'tags', 'externalDocs'];

@@ -113,4 +114,5 @@ /**

[hasKey('info'), R.compose(parseInfoObject(context), getValue)],
[hasKey('components'), R.compose(parseComponentsObject(context), getValue)],
[hasKey('paths'), R.compose(asArray, parsePathsObject(context), getValue)],
[hasKey('components'), R.compose(parseComponentsObject(context), getValue)],
[hasKey('security'), R.compose(parseSecurityRequirementsArray(context), getValue)],

@@ -130,3 +132,15 @@ // FIXME Support exposing extensions into parse result

const api = object.get('info');
const components = object.get('components');
const security = object.get('security');
if (components) {
const schemes = R.or(components.get('securitySchemes'), new namespace.elements.Array());
if (!schemes.isEmpty) {
api.push(new namespace.elements.Category(
schemes.content, { classes: ['authSchemes'] }
));
}
}
const resources = object.get('paths');

@@ -137,3 +151,16 @@ if (resources) {

const components = object.get('components');
api.resources.forEach((resource) => {
resource.transitions.forEach((transition) => {
transition.transactions.forEach((transaction) => {
if (!transaction.authSchemes && security && !security.isEmpty) {
transaction.attributes.set('authSchemes', security.clone());
}
if (transaction.authSchemes && transaction.authSchemes.isEmpty) {
transaction.attributes.remove('authSchemes');
}
});
});
});
if (components) {

@@ -140,0 +167,0 @@ const schemas = R.or(components.get('schemas'), new namespace.elements.Array())

@@ -17,2 +17,3 @@ const R = require('ramda');

const parseRequestBodyObject = require('./parseRequestBodyObject');
const parseSecurityRequirementsArray = require('./parseSecurityRequirementsArray');
const parseReference = require('../parseReference');

@@ -25,3 +26,3 @@

const unsupportedKeys = [
'tags', 'externalDocs', 'callbacks', 'deprecated', 'security',
'tags', 'externalDocs', 'callbacks', 'deprecated',
];

@@ -114,2 +115,3 @@ const isUnsupportedKey = R.anyPass(R.map(hasKey, unsupportedKeys));

[hasKey('parameters'), R.compose(parseParameterObjects(context, name), getValue)],
[hasKey('security'), R.compose(parseSecurityRequirementsArray(context), getValue)],

@@ -167,2 +169,9 @@ [isUnsupportedKey, createUnsupportedMemberWarning(namespace, name)],

const security = operation.get('security');
if (security) {
transactions.forEach((transaction) => {
transaction.attributes.set('authSchemes', security.clone());
});
}
return transition;

@@ -169,0 +178,0 @@ });

@@ -43,19 +43,43 @@ const R = require('ramda');

(securityRequirement) => {
const arr = new namespace.elements.Array([]);
const parseResult = new namespace.elements.ParseResult([]);
const array = new namespace.elements.Array([]);
securityRequirement.forEach((value, key) => {
let e;
const schemeName = key.toValue();
const scopes = value.map(scope => scope.toValue());
if (scopes.length) {
e = new namespace.elements.Object({ scopes });
e = new namespace.elements.AuthScheme({ scopes });
} else {
e = new namespace.elements.Object({});
e = new namespace.elements.AuthScheme({});
}
e.element = key.toValue();
arr.push(e);
// Expand oauth2 flows
const hasFlows = context.state.oauthFlows[schemeName] || [];
if (hasFlows.length !== 0) {
hasFlows.forEach((flow) => {
const element = e.clone();
element.element = flow;
array.push(element);
});
return;
}
if (!context.hasScheme(schemeName)) {
parseResult.push(createWarning(namespace, `'${schemeName}' security scheme not found`, key));
} else {
e.element = schemeName;
array.push(e);
}
});
return arr;
if (!array.isEmpty) {
parseResult.push(array);
}
return parseResult;
});

@@ -62,0 +86,0 @@

@@ -13,2 +13,3 @@ const R = require('ramda');

const parseString = require('../parseString');
const parseOauthFlowsObject = require('./parseOauthFlowsObject');

@@ -19,7 +20,8 @@ const name = 'Security Scheme Object';

const isUnsupportedKey = R.anyPass(R.map(hasKey, unsupportedKeys));
const passThrough = R.anyPass(R.map(hasKey, ['name', 'in', 'scheme', 'flows']));
const outerPassThrough = R.anyPass(R.map(hasKey, ['name', 'in', 'scheme', 'flows']));
const innerPassThrough = R.anyPass(R.map(hasKey, ['type', 'description']));
const isApiKeyScheme = securityScheme => securityScheme.getValue('type') === 'apiKey';
const isHttpScheme = securityScheme => securityScheme.getValue('type') === 'http';
// const isOauth2Scheme = securityScheme => securityScheme.getValue('type') === 'oauth2';
const isOauth2Scheme = securityScheme => securityScheme.getValue('type') === 'oauth2';

@@ -29,3 +31,2 @@ const isValidTypeValue = R.anyPass(R.map(hasValue, ['apiKey', 'http', 'oauth2', 'openIdConnect']));

const isValidInValue = R.anyPass(R.map(hasValue, ['query', 'header', 'cookie']));
const isSupportedIn = R.anyPass(R.map(hasValue, ['query', 'header']));

@@ -41,10 +42,5 @@ function validateApiKeyScheme(context, securityScheme) {

const createUnsupportedInWarning = member => createWarning(namespace,
`'${name}' 'in' '${member.value.toValue()}' is unsupported`, member.value);
const ensureSupportedIn = R.unless(isSupportedIn, createUnsupportedInWarning);
const parseIn = pipeParseResult(namespace,
parseString(context, name, false),
validateIn,
ensureSupportedIn);
validateIn);

@@ -55,3 +51,7 @@ const parseMember = R.cond([

[R.T, e => e],
[innerPassThrough, e => e],
[isUnsupportedKey, e => e],
[isExtension, e => e],
[R.T, createInvalidMemberWarning(namespace, `${name}' 'apiKey`)],
]);

@@ -63,6 +63,12 @@

function validateHttpScheme(context, securityScheme) {
const { namespace } = context;
const parseMember = R.cond([
[hasKey('scheme'), parseString(context, name, false)],
[R.T, e => e],
[innerPassThrough, e => e],
[isUnsupportedKey, e => e],
[isExtension, e => e],
[R.T, createInvalidMemberWarning(namespace, `${name}' 'http`)],
]);

@@ -73,2 +79,18 @@

function validateOauth2Scheme(context, securityScheme) {
const { namespace } = context;
const parseMember = R.cond([
[hasKey('flows'), R.compose(parseOauthFlowsObject(context), getValue)],
[innerPassThrough, e => e],
[isUnsupportedKey, e => e],
[isExtension, e => e],
[R.T, createInvalidMemberWarning(namespace, `${name}' 'oauth2`)],
]);
return parseObject(context, name, parseMember, ['flows'], [], true)(securityScheme);
}
/**

@@ -105,3 +127,3 @@ * Parse Security Scheme Object

[hasKey('description'), parseString(context, name, false)],
[passThrough, e => e],
[outerPassThrough, e => e],

@@ -121,3 +143,3 @@ [isUnsupportedKey, createUnsupportedMemberWarning(namespace, name)],

R.when(isHttpScheme, R.curry(validateHttpScheme)(context)),
// R.when(isOauth2Scheme, parseSecuritySchemeFlowsObject),
R.when(isOauth2Scheme, R.curry(validateOauth2Scheme)(context)),
(securityScheme) => {

@@ -128,3 +150,17 @@ const authScheme = new namespace.elements.AuthScheme();

const scheme = securityScheme.getValue('scheme');
const description = securityScheme.get('description');
if (type === 'oauth2') {
const flows = securityScheme.get('flows');
if (description) {
flows.forEach((flow) => {
// eslint-disable-next-line no-param-reassign
flow.description = description.clone();
});
}
return flows;
}
if (type === 'apiKey' || (type === 'http' && scheme === 'bearer')) {

@@ -134,5 +170,6 @@ authScheme.element = 'Token Authentication Scheme';

authScheme.element = 'Basic Authentication Scheme';
} else {
throw new Error(`Invalid security Scheme '${type}' '${scheme}'`);
}
const description = securityScheme.get('description');
if (description) {

@@ -150,2 +187,4 @@ authScheme.description = description;

key = 'queryParameterName';
} else if (inValue === 'cookie') {
key = 'cookieName';
}

@@ -152,0 +191,0 @@

@@ -114,4 +114,6 @@ /* eslint-disable no-use-before-define */

message = `${problem}, ${error.context}`;
} else if (error.context) {
message = error.context;
} else {
message = error.context;
({ message } = error);
}

@@ -125,8 +127,10 @@

const marker = error.context_mark || error.problem_mark;
copySourceMap(
marker,
marker,
annotation,
namespace
);
if (marker) {
copySourceMap(
marker,
marker,
annotation,
namespace
);
}

@@ -133,0 +137,0 @@ parseResult.push(annotation);

class State {
constructor() {
this.registeredIds = new Set();
this.registeredSchemes = new Set();
this.oauthFlows = {};
}

@@ -14,4 +17,24 @@

}
oauthFlow(id, flow) {
this.oauthFlows[id] = this.oauthFlows[id] || new Set();
this.oauthFlows[id].add(flow);
return this.registerScheme(flow);
}
registerScheme(id) {
if (this.registeredSchemes.has(id)) {
return false;
}
this.registeredSchemes.add(id);
return true;
}
hasScheme(id) {
return this.registeredSchemes.has(id);
}
}
module.exports = State;
{
"name": "fury-adapter-oas3-parser",
"version": "0.9.1",
"version": "0.10.0",
"description": "Open API Specification 3 API Elements Parser",

@@ -32,3 +32,3 @@ "author": "Apiary.io <support@apiary.io>",

"peerDependencies": {
"fury": "3.0.0-beta.12"
"fury": "3.0.0-beta.13"
},

@@ -38,3 +38,3 @@ "devDependencies": {

"eslint": "^5.16.0",
"fury": "3.0.0-beta.12",
"fury": "3.0.0-beta.13",
"mocha": "^5.2.0"

@@ -45,3 +45,3 @@ },

},
"gitHead": "35f97c5d690450c1894a6932dc217e166cb853ec"
"gitHead": "92e12bd81f6f5c873b411fa34e7df59cbe1dcc88"
}
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