Merge branch 'master' into ft/docs
This commit is contained in:
@@ -16,7 +16,8 @@
|
|||||||
"extends": ["eslint:recommended", "plugin:react/recommended"],
|
"extends": ["eslint:recommended", "plugin:react/recommended"],
|
||||||
|
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"react"
|
"react",
|
||||||
|
"mocha"
|
||||||
],
|
],
|
||||||
|
|
||||||
"rules": {
|
"rules": {
|
||||||
@@ -32,6 +33,7 @@
|
|||||||
"comma-dangle": 0,
|
"comma-dangle": 0,
|
||||||
"no-console": ["error", { allow: ["warn", "error"] }],
|
"no-console": ["error", { allow: ["warn", "error"] }],
|
||||||
"react/jsx-no-bind": 1,
|
"react/jsx-no-bind": 1,
|
||||||
"react/display-name": 0
|
"react/display-name": 0,
|
||||||
|
"mocha/no-exclusive-tests": "error"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
3
.github/issue_template.md
vendored
3
.github/issue_template.md
vendored
@@ -1,6 +1,9 @@
|
|||||||
<!---
|
<!---
|
||||||
Thanks for filing an issue 😄 ! Before you submit, please read the following:
|
Thanks for filing an issue 😄 ! Before you submit, please read the following:
|
||||||
|
|
||||||
|
If you're here to report a security issue, please STOP writing an issue and contact us
|
||||||
|
at security@swagger.io instead!
|
||||||
|
|
||||||
Search open/closed issues before submitting since someone might have asked the same thing before!
|
Search open/closed issues before submitting since someone might have asked the same thing before!
|
||||||
|
|
||||||
Issues on GitHub are only related to problems of Swagger-UI itself. We'll try to offer support
|
Issues on GitHub are only related to problems of Swagger-UI itself. We'll try to offer support
|
||||||
|
|||||||
42
.github/pull_request_template.md
vendored
Normal file
42
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<!--- Provide a general summary of your changes in the Title above -->
|
||||||
|
|
||||||
|
### Description
|
||||||
|
<!--- Describe your changes in detail -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Motivation and Context
|
||||||
|
<!--- Why is this change required? What problem does it solve? -->
|
||||||
|
<!--- If it fixes an open issue, please link to the issue here. -->
|
||||||
|
<!--- Use the magic "Fixes #1234" format, so the issues are -->
|
||||||
|
<!--- automatically closed when this PR is merged. -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### How Has This Been Tested?
|
||||||
|
<!--- Please describe in detail how you manually tested your changes. -->
|
||||||
|
<!--- Include details of your testing environment, and the tests you ran to -->
|
||||||
|
<!--- see how your change affects other areas of the code, etc. -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Screenshots (if appropriate):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Types of changes
|
||||||
|
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
|
||||||
|
- [ ] No code changes (changes to documentation, CI, metadata, etc)
|
||||||
|
- [ ] Dependency changes (any modification to dependencies in `package.json`)
|
||||||
|
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||||
|
- [ ] New feature (non-breaking change which adds functionality)
|
||||||
|
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
|
||||||
|
|
||||||
|
### Checklist:
|
||||||
|
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||||
|
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||||
|
- [ ] My code follows the code style of this project.
|
||||||
|
- [ ] My change requires a change to the documentation.
|
||||||
|
- [ ] I have updated the documentation accordingly.
|
||||||
|
- [ ] I have added tests to cover my changes.
|
||||||
|
- [ ] All new and existing tests passed.
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
**This is the new version of swagger-ui, 3.x. Want to learn more? Check out our [FAQ](http://swagger.io/new-ui-faq/).**
|
**This is the new version of swagger-ui, 3.x. Want to learn more? Check out our [FAQ](http://swagger.io/new-ui-faq/).**
|
||||||
|
|
||||||
**👉🏼 Want to score an easy open-source contribution?** Check out our [Good first contribution](https://github.com/swagger-api/swagger-ui/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+contribution%22) label.
|
**👉🏼 Want to score an easy open-source contribution?** Check out our [Good first issue](https://github.com/swagger-api/swagger-ui/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%22) label.
|
||||||
|
|
||||||
As a brand new version, written from the ground up, there are some known issues and unimplemented features. Check out the [Known Issues](#known-issues) section for more details.
|
As a brand new version, written from the ground up, there are some known issues and unimplemented features. Check out the [Known Issues](#known-issues) section for more details.
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ The OpenAPI Specification has undergone 5 revisions since initial creation in 20
|
|||||||
|
|
||||||
Swagger UI Version | Release Date | OpenAPI Spec compatibility | Notes
|
Swagger UI Version | Release Date | OpenAPI Spec compatibility | Notes
|
||||||
------------------ | ------------ | -------------------------- | -----
|
------------------ | ------------ | -------------------------- | -----
|
||||||
3.3.1 | 2017-10-02 | 2.0, 3.0 | [tag v3.3.1](https://github.com/swagger-api/swagger-ui/tree/v3.3.1)
|
3.4.2 | 2017-10-30 | 2.0, 3.0 | [tag v3.4.2](https://github.com/swagger-api/swagger-ui/tree/v3.4.2)
|
||||||
3.0.21 | 2017-07-26 | 2.0 | [tag v3.0.21](https://github.com/swagger-api/swagger-ui/tree/v3.0.21)
|
3.0.21 | 2017-07-26 | 2.0 | [tag v3.0.21](https://github.com/swagger-api/swagger-ui/tree/v3.0.21)
|
||||||
2.2.10 | 2017-01-04 | 1.1, 1.2, 2.0 | [tag v2.2.10](https://github.com/swagger-api/swagger-ui/tree/v2.2.10)
|
2.2.10 | 2017-01-04 | 1.1, 1.2, 2.0 | [tag v2.2.10](https://github.com/swagger-api/swagger-ui/tree/v2.2.10)
|
||||||
2.1.5 | 2016-07-20 | 1.1, 1.2, 2.0 | [tag v2.1.5](https://github.com/swagger-api/swagger-ui/tree/v2.1.5)
|
2.1.5 | 2016-07-20 | 1.1, 1.2, 2.0 | [tag v2.1.5](https://github.com/swagger-api/swagger-ui/tree/v2.1.5)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>Swagger UI</title>
|
<title>Swagger UI</title>
|
||||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
|
||||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
|
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
|
||||||
|
|||||||
@@ -27,7 +27,10 @@
|
|||||||
|
|
||||||
isValid = qp.state === sentState
|
isValid = qp.state === sentState
|
||||||
|
|
||||||
if (oauth2.auth.schema.get("flow") === "accessCode" && !oauth2.auth.code) {
|
if ((
|
||||||
|
oauth2.auth.schema.get("flow") === "accessCode"||
|
||||||
|
oauth2.auth.schema.get("flow") === "authorizationCode"
|
||||||
|
) && !oauth2.auth.code) {
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
oauth2.errCb({
|
oauth2.errCb({
|
||||||
authId: oauth2.auth.name,
|
authId: oauth2.auth.name,
|
||||||
|
|||||||
5
dist/oauth2-redirect.html
vendored
5
dist/oauth2-redirect.html
vendored
@@ -27,7 +27,10 @@
|
|||||||
|
|
||||||
isValid = qp.state === sentState
|
isValid = qp.state === sentState
|
||||||
|
|
||||||
if (oauth2.auth.schema.get("flow") === "accessCode" && !oauth2.auth.code) {
|
if ((
|
||||||
|
oauth2.auth.schema.get("flow") === "accessCode"||
|
||||||
|
oauth2.auth.schema.get("flow") === "authorizationCode"
|
||||||
|
) && !oauth2.auth.code) {
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
oauth2.errCb({
|
oauth2.errCb({
|
||||||
authId: oauth2.auth.name,
|
authId: oauth2.auth.name,
|
||||||
|
|||||||
92
dist/swagger-ui-bundle.js
vendored
92
dist/swagger-ui-bundle.js
vendored
File diff suppressed because one or more lines are too long
2
dist/swagger-ui-bundle.js.map
vendored
2
dist/swagger-ui-bundle.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/swagger-ui-standalone-preset.js
vendored
2
dist/swagger-ui-standalone-preset.js
vendored
File diff suppressed because one or more lines are too long
2
dist/swagger-ui-standalone-preset.js.map
vendored
2
dist/swagger-ui-standalone-preset.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/swagger-ui.css
vendored
2
dist/swagger-ui.css
vendored
File diff suppressed because one or more lines are too long
2
dist/swagger-ui.css.map
vendored
2
dist/swagger-ui.css.map
vendored
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"swagger-ui.css","sources":[],"mappings":"","sourceRoot":""}
|
{"version":3,"sources":[],"names":[],"mappings":"","file":"swagger-ui.css","sourceRoot":""}
|
||||||
4
dist/swagger-ui.js
vendored
4
dist/swagger-ui.js
vendored
File diff suppressed because one or more lines are too long
2
dist/swagger-ui.js.map
vendored
2
dist/swagger-ui.js.map
vendored
File diff suppressed because one or more lines are too long
@@ -32,7 +32,7 @@ fi
|
|||||||
|
|
||||||
if [[ -f $SWAGGER_JSON ]]; then
|
if [[ -f $SWAGGER_JSON ]]; then
|
||||||
cp $SWAGGER_JSON $NGINX_ROOT
|
cp $SWAGGER_JSON $NGINX_ROOT
|
||||||
REL_PATH="/$(basename $SWAGGER_JSON)"
|
REL_PATH="./$(basename $SWAGGER_JSON)"
|
||||||
sed -i "s|http://petstore.swagger.io/v2/swagger.json|$REL_PATH|g" $INDEX_FILE
|
sed -i "s|http://petstore.swagger.io/v2/swagger.json|$REL_PATH|g" $INDEX_FILE
|
||||||
sed -i "s|http://example.com/api|$REL_PATH|g" $INDEX_FILE
|
sed -i "s|http://example.com/api|$REL_PATH|g" $INDEX_FILE
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ module.exports = function(rules, options) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
devtool: specialOptions.sourcemaps ? "cheap-module-source-map" : null,
|
devtool: specialOptions.sourcemaps ? "nosource-source-map" : null,
|
||||||
|
|
||||||
plugins,
|
plugins,
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "swagger-ui",
|
"name": "swagger-ui",
|
||||||
"version": "3.3.1",
|
"version": "3.4.2",
|
||||||
"main": "dist/swagger-ui.js",
|
"main": "dist/swagger-ui.js",
|
||||||
"repository": "git@github.com:swagger-api/swagger-ui.git",
|
"repository": "git@github.com:swagger-api/swagger-ui.git",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
@@ -39,6 +39,7 @@
|
|||||||
"e2e": "npm-run-all --parallel -r hot-server mock-api test-e2e"
|
"e2e": "npm-run-all --parallel -r hot-server mock-api test-e2e"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@braintree/sanitize-url": "^2.0.2",
|
||||||
"base64-js": "^1.2.0",
|
"base64-js": "^1.2.0",
|
||||||
"brace": "0.7.0",
|
"brace": "0.7.0",
|
||||||
"classnames": "^2.2.5",
|
"classnames": "^2.2.5",
|
||||||
@@ -78,7 +79,7 @@
|
|||||||
"scroll-to-element": "^2.0.0",
|
"scroll-to-element": "^2.0.0",
|
||||||
"serialize-error": "2.0.0",
|
"serialize-error": "2.0.0",
|
||||||
"shallowequal": "0.2.2",
|
"shallowequal": "0.2.2",
|
||||||
"swagger-client": "^3.2.0",
|
"swagger-client": "^3.3.1",
|
||||||
"url-parse": "^1.1.8",
|
"url-parse": "^1.1.8",
|
||||||
"whatwg-fetch": "0.11.1",
|
"whatwg-fetch": "0.11.1",
|
||||||
"worker-loader": "^0.7.1",
|
"worker-loader": "^0.7.1",
|
||||||
@@ -105,6 +106,7 @@
|
|||||||
"enzyme": "^2.7.1",
|
"enzyme": "^2.7.1",
|
||||||
"eslint": "^4.1.1",
|
"eslint": "^4.1.1",
|
||||||
"eslint-plugin-import": "^2.6.0",
|
"eslint-plugin-import": "^2.6.0",
|
||||||
|
"eslint-plugin-mocha": "^4.11.0",
|
||||||
"eslint-plugin-react": "^7.1.0",
|
"eslint-plugin-react": "^7.1.0",
|
||||||
"extract-text-webpack-plugin": "^2.1.2",
|
"extract-text-webpack-plugin": "^2.1.2",
|
||||||
"file-loader": "0.11.2",
|
"file-loader": "0.11.2",
|
||||||
|
|||||||
@@ -51,14 +51,15 @@ export default class ApiKeyAuth extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h4>Api key authorization<JumpToPath path={[ "securityDefinitions", name ]} /></h4>
|
<h4>
|
||||||
|
<code>{ name || schema.get("name") }</code>
|
||||||
|
(apiKey)
|
||||||
|
<JumpToPath path={[ "securityDefinitions", name ]} />
|
||||||
|
</h4>
|
||||||
{ value && <h6>Authorized</h6>}
|
{ value && <h6>Authorized</h6>}
|
||||||
<Row>
|
<Row>
|
||||||
<Markdown source={ schema.get("description") } />
|
<Markdown source={ schema.get("description") } />
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
|
||||||
<p>Name: <code>{ schema.get("name") }</code></p>
|
|
||||||
</Row>
|
|
||||||
<Row>
|
<Row>
|
||||||
<p>In: <code>{ schema.get("in") }</code></p>
|
<p>In: <code>{ schema.get("in") }</code></p>
|
||||||
</Row>
|
</Row>
|
||||||
|
|||||||
62
src/core/components/auth/auth-item.jsx
Normal file
62
src/core/components/auth/auth-item.jsx
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import React from "react"
|
||||||
|
import PropTypes from "prop-types"
|
||||||
|
import ImPropTypes from "react-immutable-proptypes"
|
||||||
|
|
||||||
|
export default class Auths extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
schema: ImPropTypes.orderedMap.isRequired,
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
onAuthChange: PropTypes.func.isRequired,
|
||||||
|
authorized: ImPropTypes.orderedMap.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let {
|
||||||
|
schema,
|
||||||
|
name,
|
||||||
|
getComponent,
|
||||||
|
onAuthChange,
|
||||||
|
authorized,
|
||||||
|
errSelectors
|
||||||
|
} = this.props
|
||||||
|
const ApiKeyAuth = getComponent("apiKeyAuth")
|
||||||
|
const BasicAuth = getComponent("basicAuth")
|
||||||
|
|
||||||
|
let authEl
|
||||||
|
|
||||||
|
const type = schema.get("type")
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case "apiKey": authEl = <ApiKeyAuth key={ name }
|
||||||
|
schema={ schema }
|
||||||
|
name={ name }
|
||||||
|
errSelectors={ errSelectors }
|
||||||
|
authorized={ authorized }
|
||||||
|
getComponent={ getComponent }
|
||||||
|
onChange={ onAuthChange } />
|
||||||
|
break
|
||||||
|
case "basic": authEl = <BasicAuth key={ name }
|
||||||
|
schema={ schema }
|
||||||
|
name={ name }
|
||||||
|
errSelectors={ errSelectors }
|
||||||
|
authorized={ authorized }
|
||||||
|
getComponent={ getComponent }
|
||||||
|
onChange={ onAuthChange } />
|
||||||
|
break
|
||||||
|
default: authEl = <div key={ name }>Unknown security definition type { type }</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<div key={`${name}-jump`}>
|
||||||
|
{ authEl }
|
||||||
|
</div>)
|
||||||
|
}
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
errSelectors: PropTypes.object.isRequired,
|
||||||
|
getComponent: PropTypes.func.isRequired,
|
||||||
|
authSelectors: PropTypes.object.isRequired,
|
||||||
|
specSelectors: PropTypes.object.isRequired,
|
||||||
|
authActions: PropTypes.object.isRequired,
|
||||||
|
definitions: ImPropTypes.iterable.isRequired
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,7 +27,6 @@ export default class Auths extends React.Component {
|
|||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
let { authActions } = this.props
|
let { authActions } = this.props
|
||||||
|
|
||||||
authActions.authorize(this.state)
|
authActions.authorize(this.state)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,8 +43,7 @@ export default class Auths extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { definitions, getComponent, authSelectors, errSelectors } = this.props
|
let { definitions, getComponent, authSelectors, errSelectors } = this.props
|
||||||
const ApiKeyAuth = getComponent("apiKeyAuth")
|
const AuthItem = getComponent("AuthItem")
|
||||||
const BasicAuth = getComponent("basicAuth")
|
|
||||||
const Oauth2 = getComponent("oauth2", true)
|
const Oauth2 = getComponent("oauth2", true)
|
||||||
const Button = getComponent("Button")
|
const Button = getComponent("Button")
|
||||||
|
|
||||||
@@ -64,33 +62,15 @@ export default class Auths extends React.Component {
|
|||||||
!!nonOauthDefinitions.size && <form onSubmit={ this.submitAuth }>
|
!!nonOauthDefinitions.size && <form onSubmit={ this.submitAuth }>
|
||||||
{
|
{
|
||||||
nonOauthDefinitions.map( (schema, name) => {
|
nonOauthDefinitions.map( (schema, name) => {
|
||||||
let type = schema.get("type")
|
return <AuthItem
|
||||||
let authEl
|
key={name}
|
||||||
|
schema={schema}
|
||||||
switch(type) {
|
name={name}
|
||||||
case "apiKey": authEl = <ApiKeyAuth key={ name }
|
getComponent={getComponent}
|
||||||
schema={ schema }
|
onAuthChange={this.onAuthChange}
|
||||||
name={ name }
|
authorized={authorized}
|
||||||
errSelectors={ errSelectors }
|
errSelectors={errSelectors}
|
||||||
authorized={ authorized }
|
/>
|
||||||
getComponent={ getComponent }
|
|
||||||
onChange={ this.onAuthChange } />
|
|
||||||
break
|
|
||||||
case "basic": authEl = <BasicAuth key={ name }
|
|
||||||
schema={ schema }
|
|
||||||
name={ name }
|
|
||||||
errSelectors={ errSelectors }
|
|
||||||
authorized={ authorized }
|
|
||||||
getComponent={ getComponent }
|
|
||||||
onChange={ this.onAuthChange } />
|
|
||||||
break
|
|
||||||
default: authEl = <div key={ name }>Unknown security definition type { type }</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
return (<div key={`${name}-jump`}>
|
|
||||||
{ authEl }
|
|
||||||
</div>)
|
|
||||||
|
|
||||||
}).toArray()
|
}).toArray()
|
||||||
}
|
}
|
||||||
<div className="auth-btn-wrapper">
|
<div className="auth-btn-wrapper">
|
||||||
|
|||||||
@@ -2,11 +2,6 @@ import React from "react"
|
|||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import oauth2Authorize from "core/oauth2-authorize"
|
import oauth2Authorize from "core/oauth2-authorize"
|
||||||
|
|
||||||
const IMPLICIT = "implicit"
|
|
||||||
const ACCESS_CODE = "accessCode"
|
|
||||||
const PASSWORD = "password"
|
|
||||||
const APPLICATION = "application"
|
|
||||||
|
|
||||||
export default class Oauth2 extends React.Component {
|
export default class Oauth2 extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
@@ -16,6 +11,7 @@ export default class Oauth2 extends React.Component {
|
|||||||
authSelectors: PropTypes.object.isRequired,
|
authSelectors: PropTypes.object.isRequired,
|
||||||
authActions: PropTypes.object.isRequired,
|
authActions: PropTypes.object.isRequired,
|
||||||
errSelectors: PropTypes.object.isRequired,
|
errSelectors: PropTypes.object.isRequired,
|
||||||
|
specSelectors: PropTypes.object.isRequired,
|
||||||
errActions: PropTypes.object.isRequired,
|
errActions: PropTypes.object.isRequired,
|
||||||
getConfigs: PropTypes.any
|
getConfigs: PropTypes.any
|
||||||
}
|
}
|
||||||
@@ -83,7 +79,9 @@ export default class Oauth2 extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { schema, getComponent, authSelectors, errSelectors, name } = this.props
|
let {
|
||||||
|
schema, getComponent, authSelectors, errSelectors, name, specSelectors
|
||||||
|
} = this.props
|
||||||
const Input = getComponent("Input")
|
const Input = getComponent("Input")
|
||||||
const Row = getComponent("Row")
|
const Row = getComponent("Row")
|
||||||
const Col = getComponent("Col")
|
const Col = getComponent("Col")
|
||||||
@@ -92,6 +90,14 @@ export default class Oauth2 extends React.Component {
|
|||||||
const JumpToPath = getComponent("JumpToPath", true)
|
const JumpToPath = getComponent("JumpToPath", true)
|
||||||
const Markdown = getComponent( "Markdown" )
|
const Markdown = getComponent( "Markdown" )
|
||||||
|
|
||||||
|
const { isOAS3 } = specSelectors
|
||||||
|
|
||||||
|
// Auth type consts
|
||||||
|
const IMPLICIT = "implicit"
|
||||||
|
const PASSWORD = "password"
|
||||||
|
const ACCESS_CODE = isOAS3() ? "authorizationCode" : "accessCode"
|
||||||
|
const APPLICATION = isOAS3() ? "clientCredentials" : "application"
|
||||||
|
|
||||||
let flow = schema.get("flow")
|
let flow = schema.get("flow")
|
||||||
let scopes = schema.get("allowedScopes") || schema.get("scopes")
|
let scopes = schema.get("allowedScopes") || schema.get("scopes")
|
||||||
let authorizedAuth = authSelectors.authorized().get(name)
|
let authorizedAuth = authSelectors.authorized().get(name)
|
||||||
@@ -102,7 +108,7 @@ export default class Oauth2 extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h4>OAuth2.0 <JumpToPath path={[ "securityDefinitions", name ]} /></h4>
|
<h4>{name} (OAuth2, { schema.get("flow") }) <JumpToPath path={[ "securityDefinitions", name ]} /></h4>
|
||||||
{ !this.state.appName ? null : <h5>Application: { this.state.appName } </h5> }
|
{ !this.state.appName ? null : <h5>Application: { this.state.appName } </h5> }
|
||||||
{ description && <Markdown source={ schema.get("description") } /> }
|
{ description && <Markdown source={ schema.get("description") } /> }
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React from "react"
|
|||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import { fromJS } from "immutable"
|
import { fromJS } from "immutable"
|
||||||
import ImPropTypes from "react-immutable-proptypes"
|
import ImPropTypes from "react-immutable-proptypes"
|
||||||
|
import { sanitizeUrl } from "core/utils"
|
||||||
|
|
||||||
|
|
||||||
class Path extends React.Component {
|
class Path extends React.Component {
|
||||||
@@ -35,9 +36,9 @@ class Contact extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{ url && <div><a href={ url } target="_blank">{ name } - Website</a></div> }
|
{ url && <div><a href={ sanitizeUrl(url) } target="_blank">{ name } - Website</a></div> }
|
||||||
{ email &&
|
{ email &&
|
||||||
<a href={`mailto:${email}`}>
|
<a href={sanitizeUrl(`mailto:${email}`)}>
|
||||||
{ url ? `Send email to ${name}` : `Contact ${name}`}
|
{ url ? `Send email to ${name}` : `Contact ${name}`}
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
@@ -59,7 +60,7 @@ class License extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{
|
{
|
||||||
url ? <a target="_blank" href={ url }>{ name }</a>
|
url ? <a target="_blank" href={ sanitizeUrl(url) }>{ name }</a>
|
||||||
: <span>{ name }</span>
|
: <span>{ name }</span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -97,7 +98,7 @@ export default class Info extends React.Component {
|
|||||||
{ version && <VersionStamp version={version}></VersionStamp> }
|
{ version && <VersionStamp version={version}></VersionStamp> }
|
||||||
</h2>
|
</h2>
|
||||||
{ host || basePath ? <Path host={ host } basePath={ basePath } /> : null }
|
{ host || basePath ? <Path host={ host } basePath={ basePath } /> : null }
|
||||||
{ url && <a target="_blank" href={ url }><span className="url"> { url } </span></a> }
|
{ url && <a target="_blank" href={ sanitizeUrl(url) }><span className="url"> { url } </span></a> }
|
||||||
</hgroup>
|
</hgroup>
|
||||||
|
|
||||||
<div className="description">
|
<div className="description">
|
||||||
@@ -106,14 +107,14 @@ export default class Info extends React.Component {
|
|||||||
|
|
||||||
{
|
{
|
||||||
termsOfService && <div>
|
termsOfService && <div>
|
||||||
<a target="_blank" href={ termsOfService }>Terms of service</a>
|
<a target="_blank" href={ sanitizeUrl(termsOfService) }>Terms of service</a>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
{ contact && contact.size ? <Contact data={ contact } /> : null }
|
{ contact && contact.size ? <Contact data={ contact } /> : null }
|
||||||
{ license && license.size ? <License license={ license } /> : null }
|
{ license && license.size ? <License license={ license } /> : null }
|
||||||
{ externalDocsUrl ?
|
{ externalDocsUrl ?
|
||||||
<a target="_blank" href={externalDocsUrl}>{externalDocsDescription || externalDocsUrl}</a>
|
<a target="_blank" href={sanitizeUrl(externalDocsUrl)}>{externalDocsDescription || externalDocsUrl}</a>
|
||||||
: null }
|
: null }
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
|
import { sanitizeUrl } from "core/utils"
|
||||||
|
|
||||||
export default class OnlineValidatorBadge extends React.Component {
|
export default class OnlineValidatorBadge extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@@ -32,6 +33,8 @@ export default class OnlineValidatorBadge extends React.Component {
|
|||||||
let { getConfigs } = this.props
|
let { getConfigs } = this.props
|
||||||
let { spec } = getConfigs()
|
let { spec } = getConfigs()
|
||||||
|
|
||||||
|
let sanitizedValidatorUrl = sanitizeUrl(this.state.validatorUrl)
|
||||||
|
|
||||||
if ( typeof spec === "object" && Object.keys(spec).length) return null
|
if ( typeof spec === "object" && Object.keys(spec).length) return null
|
||||||
|
|
||||||
if (!this.state.url || !this.state.validatorUrl || this.state.url.indexOf("localhost") >= 0
|
if (!this.state.url || !this.state.validatorUrl || this.state.url.indexOf("localhost") >= 0
|
||||||
@@ -40,8 +43,8 @@ export default class OnlineValidatorBadge extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (<span style={{ float: "right"}}>
|
return (<span style={{ float: "right"}}>
|
||||||
<a target="_blank" href={`${ this.state.validatorUrl }/debug?url=${ this.state.url }`}>
|
<a target="_blank" href={`${ sanitizedValidatorUrl }/debug?url=${ this.state.url }`}>
|
||||||
<ValidatorImage src={`${ this.state.validatorUrl }?url=${ this.state.url }`} alt="Online validator badge"/>
|
<ValidatorImage src={`${ sanitizedValidatorUrl }?url=${ this.state.url }`} alt="Online validator badge"/>
|
||||||
</a>
|
</a>
|
||||||
</span>)
|
</span>)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React, { PureComponent } from "react"
|
|||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import { getList } from "core/utils"
|
import { getList } from "core/utils"
|
||||||
import * as CustomPropTypes from "core/proptypes"
|
import * as CustomPropTypes from "core/proptypes"
|
||||||
|
import { sanitizeUrl } from "core/utils"
|
||||||
|
|
||||||
//import "less/opblock"
|
//import "less/opblock"
|
||||||
|
|
||||||
@@ -206,7 +207,7 @@ export default class Operation extends PureComponent {
|
|||||||
<span className="opblock-external-docs__description">
|
<span className="opblock-external-docs__description">
|
||||||
<Markdown source={ externalDocs.get("description") } />
|
<Markdown source={ externalDocs.get("description") } />
|
||||||
</span>
|
</span>
|
||||||
<a className="opblock-external-docs__link" href={ externalDocs.get("url") }>{ externalDocs.get("url") }</a>
|
<a className="opblock-external-docs__link" href={ sanitizeUrl(externalDocs.get("url")) }>{ externalDocs.get("url") }</a>
|
||||||
</div>
|
</div>
|
||||||
</div> : null
|
</div> : null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import { helpers } from "swagger-client"
|
import { helpers } from "swagger-client"
|
||||||
import { createDeepLinkPath } from "core/utils"
|
import { createDeepLinkPath, sanitizeUrl } from "core/utils"
|
||||||
const { opId } = helpers
|
const { opId } = helpers
|
||||||
|
|
||||||
export default class Operations extends React.Component {
|
export default class Operations extends React.Component {
|
||||||
@@ -101,7 +101,7 @@ export default class Operations extends React.Component {
|
|||||||
{ tagExternalDocsUrl ? ": " : null }
|
{ tagExternalDocsUrl ? ": " : null }
|
||||||
{ tagExternalDocsUrl ?
|
{ tagExternalDocsUrl ?
|
||||||
<a
|
<a
|
||||||
href={tagExternalDocsUrl}
|
href={sanitizeUrl(tagExternalDocsUrl)}
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
target={"_blank"}
|
target={"_blank"}
|
||||||
>{tagExternalDocsUrl}</a> : null
|
>{tagExternalDocsUrl}</a> : null
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React, { Component } from "react"
|
import React, { Component } from "react"
|
||||||
|
import { Map } from "immutable"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import win from "core/window"
|
import win from "core/window"
|
||||||
|
|
||||||
@@ -29,11 +30,21 @@ export default class ParameterRow extends Component {
|
|||||||
|
|
||||||
componentWillReceiveProps(props) {
|
componentWillReceiveProps(props) {
|
||||||
let { specSelectors, pathMethod, param } = props
|
let { specSelectors, pathMethod, param } = props
|
||||||
|
let { isOAS3 } = specSelectors
|
||||||
|
|
||||||
let example = param.get("example")
|
let example = param.get("example")
|
||||||
let defaultValue = param.get("default")
|
let defaultValue = param.get("default")
|
||||||
let parameter = specSelectors.getParameter(pathMethod, param.get("name"), param.get("in"))
|
let parameter = specSelectors.getParameter(pathMethod, param.get("name"), param.get("in"))
|
||||||
|
let enumValue
|
||||||
|
|
||||||
|
if(isOAS3()) {
|
||||||
|
let schema = param.get("schema") || Map()
|
||||||
|
enumValue = schema.get("enum")
|
||||||
|
} else {
|
||||||
|
enumValue = parameter ? parameter.get("enum") : undefined
|
||||||
|
}
|
||||||
let paramValue = parameter ? parameter.get("value") : undefined
|
let paramValue = parameter ? parameter.get("value") : undefined
|
||||||
let enumValue = parameter ? parameter.get("enum") : undefined
|
|
||||||
let value
|
let value
|
||||||
|
|
||||||
if ( paramValue !== undefined ) {
|
if ( paramValue !== undefined ) {
|
||||||
@@ -115,7 +126,7 @@ export default class ParameterRow extends Component {
|
|||||||
required={ required }
|
required={ required }
|
||||||
description={param.get("description") ? `${param.get("name")} - ${param.get("description")}` : `${param.get("name")}`}
|
description={param.get("description") ? `${param.get("name")} - ${param.get("description")}` : `${param.get("name")}`}
|
||||||
onChange={ this.onChangeWrapper }
|
onChange={ this.onChangeWrapper }
|
||||||
schema={ param }/>
|
schema={ isOAS3 && isOAS3() ? param.get("schema") : param }/>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ export default Markdown
|
|||||||
const sanitizeOptions = {
|
const sanitizeOptions = {
|
||||||
allowedTags: sanitize.defaults.allowedTags.concat([ "h1", "h2", "img" ]),
|
allowedTags: sanitize.defaults.allowedTags.concat([ "h1", "h2", "img" ]),
|
||||||
allowedAttributes: {
|
allowedAttributes: {
|
||||||
|
...sanitize.defaults.allowedAttributes,
|
||||||
"img": sanitize.defaults.allowedAttributes.img.concat(["title"])
|
"img": sanitize.defaults.allowedAttributes.img.concat(["title"])
|
||||||
},
|
},
|
||||||
textFilter: function(text) {
|
textFilter: function(text) {
|
||||||
|
|||||||
@@ -22,6 +22,16 @@ export default function authorize ( { auth, authActions, errActions, configs, au
|
|||||||
case "implicit":
|
case "implicit":
|
||||||
query.push("response_type=token")
|
query.push("response_type=token")
|
||||||
break
|
break
|
||||||
|
|
||||||
|
case "clientCredentials":
|
||||||
|
// OAS3
|
||||||
|
authActions.authorizeApplication(auth)
|
||||||
|
return
|
||||||
|
|
||||||
|
case "authorizationCode":
|
||||||
|
// OAS3
|
||||||
|
query.push("response_type=code")
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof clientId === "string") {
|
if (typeof clientId === "string") {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export default {
|
|||||||
securities.entrySeq().forEach( ([ key, security ]) => {
|
securities.entrySeq().forEach( ([ key, security ]) => {
|
||||||
let type = security.getIn(["schema", "type"])
|
let type = security.getIn(["schema", "type"])
|
||||||
|
|
||||||
if ( type === "apiKey" ) {
|
if ( type === "apiKey" || type === "http" ) {
|
||||||
map = map.set(key, security)
|
map = map.set(key, security)
|
||||||
} else if ( type === "basic" ) {
|
} else if ( type === "basic" ) {
|
||||||
let username = security.getIn(["value", "username"])
|
let username = security.getIn(["value", "username"])
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export const shownDefinitions = createSelector(
|
|||||||
|
|
||||||
export const definitionsToAuthorize = createSelector(
|
export const definitionsToAuthorize = createSelector(
|
||||||
state,
|
state,
|
||||||
() =>( { specSelectors } ) => {
|
() => ( { specSelectors } ) => {
|
||||||
let definitions = specSelectors.securityDefinitions()
|
let definitions = specSelectors.securityDefinitions()
|
||||||
let list = List()
|
let list = List()
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ export const definitionsToAuthorize = createSelector(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
export const getDefinitionsByNames = ( state, securities ) =>( { specSelectors } ) => {
|
export const getDefinitionsByNames = ( state, securities ) => ( { specSelectors } ) => {
|
||||||
let securityDefinitions = specSelectors.securityDefinitions()
|
let securityDefinitions = specSelectors.securityDefinitions()
|
||||||
let result = List()
|
let result = List()
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ export const authorized = createSelector(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
export const isAuthorized = ( state, securities ) =>( { authSelectors } ) => {
|
export const isAuthorized = ( state, securities ) => ( { authSelectors } ) => {
|
||||||
let authorized = authSelectors.authorized()
|
let authorized = authSelectors.authorized()
|
||||||
|
|
||||||
if(!List.isList(securities)) {
|
if(!List.isList(securities)) {
|
||||||
|
|||||||
@@ -1,29 +1,60 @@
|
|||||||
import { createSelector } from "reselect"
|
import { createSelector } from "reselect"
|
||||||
import { List } from "immutable"
|
import { List, Map, fromJS } from "immutable"
|
||||||
import { isOAS3 as isOAS3Helper } from "../helpers"
|
import { isOAS3 as isOAS3Helper } from "../helpers"
|
||||||
|
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
|
const state = state => state
|
||||||
|
|
||||||
function onlyOAS3(selector) {
|
function onlyOAS3(selector) {
|
||||||
return (ori, system) => (...args) => {
|
return (ori, system) => (state, ...args) => {
|
||||||
const spec = system.getSystem().specSelectors.specJson()
|
const spec = system.getSystem().specSelectors.specJson()
|
||||||
if(isOAS3Helper(spec)) {
|
if(isOAS3Helper(spec)) {
|
||||||
return selector(...args)
|
return selector(system, ...args)
|
||||||
} else {
|
} else {
|
||||||
return ori(...args)
|
return ori(...args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const nullSelector = createSelector(() => null)
|
export const definitionsToAuthorize = onlyOAS3(createSelector(
|
||||||
|
state,
|
||||||
|
({specSelectors}) => specSelectors.securityDefinitions(),
|
||||||
|
(system, definitions) => {
|
||||||
|
// Coerce our OpenAPI 3.0 definitions into monoflow definitions
|
||||||
|
// that look like Swagger2 definitions.
|
||||||
|
let list = List()
|
||||||
|
|
||||||
const OAS3NullSelector = onlyOAS3(nullSelector)
|
definitions.entrySeq().forEach( ([ defName, definition ]) => {
|
||||||
|
const type = definition.get("type")
|
||||||
|
|
||||||
// Hasta la vista, authentication!
|
if(type === "oauth2") {
|
||||||
export const shownDefinitions = OAS3NullSelector
|
definition.get("flows").entrySeq().forEach(([flowKey, flowVal]) => {
|
||||||
export const definitionsToAuthorize = OAS3NullSelector
|
let translatedDef = fromJS({
|
||||||
export const getDefinitionsByNames = OAS3NullSelector
|
flow: flowKey,
|
||||||
export const authorized = onlyOAS3(() => List())
|
authorizationUrl: flowVal.get("authorizationUrl"),
|
||||||
export const isAuthorized = OAS3NullSelector
|
tokenUrl: flowVal.get("tokenUrl"),
|
||||||
export const getConfigs = OAS3NullSelector
|
scopes: flowVal.get("scopes"),
|
||||||
|
type: definition.get("type")
|
||||||
|
})
|
||||||
|
|
||||||
|
list = list.push(new Map({
|
||||||
|
[defName]: translatedDef.filter((v) => {
|
||||||
|
// filter out unset values, sometimes `authorizationUrl`
|
||||||
|
// and `tokenUrl` come out as `undefined` in the data
|
||||||
|
return v !== undefined
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if(type === "http" || type === "apiKey") {
|
||||||
|
list = list.push(new Map({
|
||||||
|
[defName]: definition
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
))
|
||||||
|
|||||||
134
src/core/plugins/oas3/components/http-auth.jsx
Normal file
134
src/core/plugins/oas3/components/http-auth.jsx
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
import React from "react"
|
||||||
|
import PropTypes from "prop-types"
|
||||||
|
|
||||||
|
export default class HttpAuth extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
authorized: PropTypes.object,
|
||||||
|
getComponent: PropTypes.func.isRequired,
|
||||||
|
errSelectors: PropTypes.object.isRequired,
|
||||||
|
schema: PropTypes.object.isRequired,
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
onChange: PropTypes.func
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context)
|
||||||
|
let { name, schema } = this.props
|
||||||
|
let value = this.getValue()
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
name: name,
|
||||||
|
schema: schema,
|
||||||
|
value: value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getValue () {
|
||||||
|
let { name, authorized } = this.props
|
||||||
|
|
||||||
|
return authorized && authorized.getIn([name, "value"])
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange =(e) => {
|
||||||
|
let { onChange } = this.props
|
||||||
|
let { value, name } = e.target
|
||||||
|
|
||||||
|
let newValue = this.state.value || {}
|
||||||
|
if(name) {
|
||||||
|
newValue[name] = value
|
||||||
|
} else {
|
||||||
|
newValue = value
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ value: newValue }, () => onChange(this.state))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let { schema, getComponent, errSelectors, name } = this.props
|
||||||
|
const Input = getComponent("Input")
|
||||||
|
const Row = getComponent("Row")
|
||||||
|
const Col = getComponent("Col")
|
||||||
|
const AuthError = getComponent("authError")
|
||||||
|
const Markdown = getComponent( "Markdown" )
|
||||||
|
const JumpToPath = getComponent("JumpToPath", true)
|
||||||
|
|
||||||
|
const scheme = schema.get("scheme")
|
||||||
|
let value = this.getValue()
|
||||||
|
let errors = errSelectors.allErrors().filter( err => err.get("authId") === name)
|
||||||
|
|
||||||
|
if(scheme === "basic") {
|
||||||
|
let username = value ? value.get("username") : null
|
||||||
|
return <div>
|
||||||
|
<h4>
|
||||||
|
<code>{ name || schema.get("name") }</code>
|
||||||
|
(http, Basic)
|
||||||
|
<JumpToPath path={[ "securityDefinitions", name ]} />
|
||||||
|
</h4>
|
||||||
|
{ username && <h6>Authorized</h6> }
|
||||||
|
<Row>
|
||||||
|
<Markdown source={ schema.get("description") } />
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<label>Username:</label>
|
||||||
|
{
|
||||||
|
username ? <code> { username } </code>
|
||||||
|
: <Col><Input type="text" required="required" name="username" onChange={ this.onChange }/></Col>
|
||||||
|
}
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<label>Password:</label>
|
||||||
|
{
|
||||||
|
username ? <code> ****** </code>
|
||||||
|
: <Col><Input required="required"
|
||||||
|
autoComplete="new-password"
|
||||||
|
name="password"
|
||||||
|
type="password"
|
||||||
|
onChange={ this.onChange }/></Col>
|
||||||
|
}
|
||||||
|
</Row>
|
||||||
|
{
|
||||||
|
errors.valueSeq().map( (error, key) => {
|
||||||
|
return <AuthError error={ error }
|
||||||
|
key={ key }/>
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
if(scheme === "bearer") {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h4>
|
||||||
|
<code>{ name || schema.get("name") }</code>
|
||||||
|
(http, Bearer)
|
||||||
|
<JumpToPath path={[ "securityDefinitions", name ]} />
|
||||||
|
</h4>
|
||||||
|
{ value && <h6>Authorized</h6>}
|
||||||
|
<Row>
|
||||||
|
<Markdown source={ schema.get("description") } />
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<p>In: <code>{ schema.get("in") }</code></p>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<label>Value:</label>
|
||||||
|
{
|
||||||
|
value ? <code> ****** </code>
|
||||||
|
: <Col><Input type="text" onChange={ this.onChange }/></Col>
|
||||||
|
}
|
||||||
|
</Row>
|
||||||
|
{
|
||||||
|
errors.valueSeq().map( (error, key) => {
|
||||||
|
return <AuthError error={ error }
|
||||||
|
key={ key }/>
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return <div>
|
||||||
|
<em><b>{name}</b> HTTP authentication: unsupported or missing scheme</em>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,9 +3,11 @@ import RequestBody from "./request-body"
|
|||||||
import OperationLink from "./operation-link.jsx"
|
import OperationLink from "./operation-link.jsx"
|
||||||
import Servers from "./servers"
|
import Servers from "./servers"
|
||||||
import RequestBodyEditor from "./request-body-editor"
|
import RequestBodyEditor from "./request-body-editor"
|
||||||
|
import HttpAuth from "./http-auth"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
Callbacks,
|
Callbacks,
|
||||||
|
HttpAuth,
|
||||||
RequestBody,
|
RequestBody,
|
||||||
Servers,
|
Servers,
|
||||||
RequestBodyEditor,
|
RequestBodyEditor,
|
||||||
|
|||||||
@@ -48,12 +48,16 @@ export const definitions = onlyOAS3(createSelector(
|
|||||||
spec => spec.getIn(["components", "schemas"]) || Map()
|
spec => spec.getIn(["components", "schemas"]) || Map()
|
||||||
))
|
))
|
||||||
|
|
||||||
|
export const securityDefinitions = onlyOAS3(createSelector(
|
||||||
|
spec,
|
||||||
|
spec => spec.getIn(["components", "securitySchemes"]) || null
|
||||||
|
))
|
||||||
|
|
||||||
export const host = OAS3NullSelector
|
export const host = OAS3NullSelector
|
||||||
export const basePath = OAS3NullSelector
|
export const basePath = OAS3NullSelector
|
||||||
export const consumes = OAS3NullSelector
|
export const consumes = OAS3NullSelector
|
||||||
export const produces = OAS3NullSelector
|
export const produces = OAS3NullSelector
|
||||||
export const schemes = OAS3NullSelector
|
export const schemes = OAS3NullSelector
|
||||||
export const securityDefinitions = OAS3NullSelector
|
|
||||||
|
|
||||||
// New selectors
|
// New selectors
|
||||||
|
|
||||||
|
|||||||
23
src/core/plugins/oas3/wrap-components/auth-item.jsx
Normal file
23
src/core/plugins/oas3/wrap-components/auth-item.jsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import React from "react"
|
||||||
|
import { OAS3ComponentWrapFactory } from "../helpers"
|
||||||
|
|
||||||
|
export default OAS3ComponentWrapFactory(({ Ori, ...props }) => {
|
||||||
|
const {
|
||||||
|
schema, getComponent, errSelectors, authorized, onAuthChange, name
|
||||||
|
} = props
|
||||||
|
|
||||||
|
const HttpAuth = getComponent("HttpAuth")
|
||||||
|
const type = schema.get("type")
|
||||||
|
|
||||||
|
if(type === "http") {
|
||||||
|
return <HttpAuth key={ name }
|
||||||
|
schema={ schema }
|
||||||
|
name={ name }
|
||||||
|
errSelectors={ errSelectors }
|
||||||
|
authorized={ authorized }
|
||||||
|
getComponent={ getComponent }
|
||||||
|
onChange={ onAuthChange }/>
|
||||||
|
} else {
|
||||||
|
return <Ori {...props} />
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import Markdown from "./markdown"
|
import Markdown from "./markdown"
|
||||||
|
import AuthItem from "./auth-item"
|
||||||
import parameters from "./parameters"
|
import parameters from "./parameters"
|
||||||
import VersionStamp from "./version-stamp"
|
import VersionStamp from "./version-stamp"
|
||||||
import OnlineValidatorBadge from "./online-validator-badge"
|
import OnlineValidatorBadge from "./online-validator-badge"
|
||||||
@@ -6,6 +7,7 @@ import Model from "./model"
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
Markdown,
|
Markdown,
|
||||||
|
AuthItem,
|
||||||
parameters,
|
parameters,
|
||||||
VersionStamp,
|
VersionStamp,
|
||||||
model: Model,
|
model: Model,
|
||||||
|
|||||||
@@ -80,7 +80,12 @@ export const parseToJson = (str) => ({specActions, specSelectors, errActions}) =
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const resolveSpec = (json, url) => ({specActions, specSelectors, errActions, fn: { fetch, resolve, AST }, getConfigs}) => {
|
export const resolveSpec = (json, url) => ({specActions, specSelectors, errActions, fn: { fetch, resolve, AST }, getConfigs}) => {
|
||||||
const { modelPropertyMacro, parameterMacro } = getConfigs()
|
const {
|
||||||
|
modelPropertyMacro,
|
||||||
|
parameterMacro,
|
||||||
|
requestInterceptor,
|
||||||
|
responseInterceptor
|
||||||
|
} = getConfigs()
|
||||||
|
|
||||||
if(typeof(json) === "undefined") {
|
if(typeof(json) === "undefined") {
|
||||||
json = specSelectors.specJson()
|
json = specSelectors.specJson()
|
||||||
@@ -93,8 +98,15 @@ export const resolveSpec = (json, url) => ({specActions, specSelectors, errActio
|
|||||||
|
|
||||||
let specStr = specSelectors.specStr()
|
let specStr = specSelectors.specStr()
|
||||||
|
|
||||||
return resolve({fetch, spec: json, baseDoc: url, modelPropertyMacro, parameterMacro })
|
return resolve({
|
||||||
.then( ({spec, errors}) => {
|
fetch,
|
||||||
|
spec: json,
|
||||||
|
baseDoc: url,
|
||||||
|
modelPropertyMacro,
|
||||||
|
parameterMacro,
|
||||||
|
requestInterceptor,
|
||||||
|
responseInterceptor
|
||||||
|
}).then( ({spec, errors}) => {
|
||||||
errActions.clear({
|
errActions.clear({
|
||||||
type: "thrown"
|
type: "thrown"
|
||||||
})
|
})
|
||||||
@@ -137,10 +149,13 @@ export function changeParam( path, paramName, paramIn, value, isXml ){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validateParams( payload ){
|
export const validateParams = ( payload, isOAS3 ) =>{
|
||||||
return {
|
return {
|
||||||
type: VALIDATE_PARAMS,
|
type: VALIDATE_PARAMS,
|
||||||
payload:{ pathMethod: payload }
|
payload:{
|
||||||
|
pathMethod: payload,
|
||||||
|
isOAS3
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,14 +51,14 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
[VALIDATE_PARAMS]: ( state, { payload: { pathMethod } } ) => {
|
[VALIDATE_PARAMS]: ( state, { payload: { pathMethod, isOAS3 } } ) => {
|
||||||
let operation = state.getIn( [ "resolved", "paths", ...pathMethod ] )
|
let operation = state.getIn( [ "resolved", "paths", ...pathMethod ] )
|
||||||
let isXml = /xml/i.test(operation.get("consumes_value"))
|
let isXml = /xml/i.test(operation.get("consumes_value"))
|
||||||
|
|
||||||
return state.updateIn( [ "resolved", "paths", ...pathMethod, "parameters" ], fromJS([]), parameters => {
|
return state.updateIn( [ "resolved", "paths", ...pathMethod, "parameters" ], fromJS([]), parameters => {
|
||||||
return parameters.withMutations( parameters => {
|
return parameters.withMutations( parameters => {
|
||||||
for ( let i = 0, len = parameters.count(); i < len; i++ ) {
|
for ( let i = 0, len = parameters.count(); i < len; i++ ) {
|
||||||
let errors = validateParam(parameters.get(i), isXml)
|
let errors = validateParam(parameters.get(i), isXml, isOAS3)
|
||||||
parameters.setIn([i, "errors"], fromJS(errors))
|
parameters.setIn([i, "errors"], fromJS(errors))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,3 +13,7 @@ export const executeRequest = (ori, { specActions }) => (req) => {
|
|||||||
specActions.logRequest(req)
|
specActions.logRequest(req)
|
||||||
return ori(req)
|
return ori(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const validateParams = (ori, { specSelectors }) => (req) => {
|
||||||
|
return ori(req, specSelectors.isOAS3())
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ import AuthorizationPopup from "core/components/auth/authorization-popup"
|
|||||||
import AuthorizeBtn from "core/components/auth/authorize-btn"
|
import AuthorizeBtn from "core/components/auth/authorize-btn"
|
||||||
import AuthorizeOperationBtn from "core/components/auth/authorize-operation-btn"
|
import AuthorizeOperationBtn from "core/components/auth/authorize-operation-btn"
|
||||||
import Auths from "core/components/auth/auths"
|
import Auths from "core/components/auth/auths"
|
||||||
|
import AuthItem from "core/components/auth/auth-item"
|
||||||
import AuthError from "core/components/auth/error"
|
import AuthError from "core/components/auth/error"
|
||||||
import ApiKeyAuth from "core/components/auth/api-key-auth"
|
import ApiKeyAuth from "core/components/auth/api-key-auth"
|
||||||
import BasicAuth from "core/components/auth/basic-auth"
|
import BasicAuth from "core/components/auth/basic-auth"
|
||||||
@@ -70,6 +71,7 @@ export default function() {
|
|||||||
authorizeBtn: AuthorizeBtn,
|
authorizeBtn: AuthorizeBtn,
|
||||||
authorizeOperationBtn: AuthorizeOperationBtn,
|
authorizeOperationBtn: AuthorizeOperationBtn,
|
||||||
auths: Auths,
|
auths: Auths,
|
||||||
|
AuthItem: AuthItem,
|
||||||
authError: AuthError,
|
authError: AuthError,
|
||||||
oauth2: Oauth2,
|
oauth2: Oauth2,
|
||||||
apiKeyAuth: ApiKeyAuth,
|
apiKeyAuth: ApiKeyAuth,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import Im from "immutable"
|
import Im from "immutable"
|
||||||
|
import { sanitizeUrl as braintreeSanitizeUrl } from "@braintree/sanitize-url"
|
||||||
import camelCase from "lodash/camelCase"
|
import camelCase from "lodash/camelCase"
|
||||||
import upperFirst from "lodash/upperFirst"
|
import upperFirst from "lodash/upperFirst"
|
||||||
import _memoize from "lodash/memoize"
|
import _memoize from "lodash/memoize"
|
||||||
@@ -537,16 +537,18 @@ export const validateMinLength = (val, min) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// validation of parameters before execute
|
// validation of parameters before execute
|
||||||
export const validateParam = (param, isXml) => {
|
export const validateParam = (param, isXml, isOAS3 = false) => {
|
||||||
let errors = []
|
let errors = []
|
||||||
let value = isXml && param.get("in") === "body" ? param.get("value_xml") : param.get("value")
|
let value = isXml && param.get("in") === "body" ? param.get("value_xml") : param.get("value")
|
||||||
let required = param.get("required")
|
let required = param.get("required")
|
||||||
let maximum = param.get("maximum")
|
|
||||||
let minimum = param.get("minimum")
|
let paramDetails = isOAS3 ? param.get("schema") : param
|
||||||
let type = param.get("type")
|
let maximum = paramDetails.get("maximum")
|
||||||
let format = param.get("format")
|
let minimum = paramDetails.get("minimum")
|
||||||
let maxLength = param.get("maxLength")
|
let type = paramDetails.get("type")
|
||||||
let minLength = param.get("minLength")
|
let format = paramDetails.get("format")
|
||||||
|
let maxLength = paramDetails.get("maxLength")
|
||||||
|
let minLength = paramDetails.get("minLength")
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If the parameter is required OR the parameter has a value (meaning optional, but filled in)
|
If the parameter is required OR the parameter has a value (meaning optional, but filled in)
|
||||||
@@ -616,7 +618,7 @@ export const validateParam = (param, isXml) => {
|
|||||||
|
|
||||||
if ( !value.count() ) { return errors }
|
if ( !value.count() ) { return errors }
|
||||||
|
|
||||||
itemType = param.getIn(["items", "type"])
|
itemType = paramDetails.getIn(["items", "type"])
|
||||||
|
|
||||||
value.forEach((item, index) => {
|
value.forEach((item, index) => {
|
||||||
let err
|
let err
|
||||||
@@ -720,6 +722,14 @@ export const shallowEqualKeys = (a,b, keys) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function sanitizeUrl(url) {
|
||||||
|
if(typeof url !== "string" || url === "") {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return braintreeSanitizeUrl(url)
|
||||||
|
}
|
||||||
|
|
||||||
export function getAcceptControllingResponse(responses) {
|
export function getAcceptControllingResponse(responses) {
|
||||||
if(!Im.OrderedMap.isOrderedMap(responses)) {
|
if(!Im.OrderedMap.isOrderedMap(responses)) {
|
||||||
// wrong type!
|
// wrong type!
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Add a plugin
|
# Add a plugin
|
||||||
|
|
||||||
### Swagger-UX relies on plugins for all the good stuff.
|
### Swagger-UI relies on plugins for all the good stuff.
|
||||||
|
|
||||||
Plugins allow you to add
|
Plugins allow you to add
|
||||||
- `statePlugins`
|
- `statePlugins`
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ export default class Topbar extends React.Component {
|
|||||||
<div className="topbar">
|
<div className="topbar">
|
||||||
<div className="wrapper">
|
<div className="wrapper">
|
||||||
<div className="topbar-wrapper">
|
<div className="topbar-wrapper">
|
||||||
<Link href="#" title="Swagger UX">
|
<Link href="#">
|
||||||
<img height="30" width="30" src={ Logo } alt="Swagger UI"/>
|
<img height="30" width="30" src={ Logo } alt="Swagger UI"/>
|
||||||
<span>swagger</span>
|
<span>swagger</span>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ select
|
|||||||
.opblock-body select
|
.opblock-body select
|
||||||
{
|
{
|
||||||
min-width: 230px;
|
min-width: 230px;
|
||||||
|
@media (max-width: 768px)
|
||||||
|
{
|
||||||
|
min-width: 180px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
label
|
label
|
||||||
@@ -56,6 +60,10 @@ input[type=file]
|
|||||||
border: 1px solid #d9d9d9;
|
border: 1px solid #d9d9d9;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
max-width: 175px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
&.invalid
|
&.invalid
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -250,6 +250,10 @@
|
|||||||
.opblock-summary-path__deprecated
|
.opblock-summary-path__deprecated
|
||||||
{
|
{
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 0 3 auto;
|
flex: 0 3 auto;
|
||||||
@@ -768,14 +772,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.renderedMarkdown {
|
|
||||||
p {
|
|
||||||
@include text_body();
|
|
||||||
margin-top: 0px;
|
|
||||||
margin-bottom: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.response-content-type {
|
.response-content-type {
|
||||||
padding-top: 1em;
|
padding-top: 1em;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
.topbar
|
.topbar
|
||||||
{
|
{
|
||||||
padding: 8px 30px;
|
padding: 8px 0;
|
||||||
|
|
||||||
background-color: #89bf04;
|
background-color: #89bf04;
|
||||||
.topbar-wrapper
|
.topbar-wrapper
|
||||||
@@ -39,7 +39,6 @@
|
|||||||
input[type=text]
|
input[type=text]
|
||||||
{
|
{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 350px;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
border: 2px solid #547f00;
|
border: 2px solid #547f00;
|
||||||
@@ -84,7 +83,7 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
padding: 4px 40px;
|
padding: 4px 30px;
|
||||||
|
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 0 4px 4px 0;
|
border-radius: 0 4px 4px 0;
|
||||||
|
|||||||
@@ -24,6 +24,12 @@ describe("Markdown component", function() {
|
|||||||
const el = render(<Markdown source={str} />)
|
const el = render(<Markdown source={str} />)
|
||||||
expect(el.html()).toEqual(`<div class="markdown"><h1>h1</h1>\n<h2>h2</h2>\n<h3>h3</h3>\n<h4>h4</h4>\n<h5>h5</h5>\n<h6>h6</h6>\n</div>`)
|
expect(el.html()).toEqual(`<div class="markdown"><h1>h1</h1>\n<h2>h2</h2>\n<h3>h3</h3>\n<h4>h4</h4>\n<h5>h5</h5>\n<h6>h6</h6>\n</div>`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("allows links", function() {
|
||||||
|
const str = `[Link](https://example.com/)`
|
||||||
|
const el = render(<Markdown source={str} />)
|
||||||
|
expect(el.html()).toEqual(`<div class="markdown"><p><a href="https://example.com/" target="_blank">Link</a></p>\n</div>`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("OAS 3", function() {
|
describe("OAS 3", function() {
|
||||||
|
|||||||
116
test/core/plugins/oas3/wrap-auth-selectors.js
Normal file
116
test/core/plugins/oas3/wrap-auth-selectors.js
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/* eslint-env mocha */
|
||||||
|
import expect, { createSpy } from "expect"
|
||||||
|
import { Map, fromJS } from "immutable"
|
||||||
|
import {
|
||||||
|
definitionsToAuthorize
|
||||||
|
} from "corePlugins/oas3/auth-extensions/wrap-selectors"
|
||||||
|
|
||||||
|
describe("oas3 plugin - auth extensions - wrapSelectors", function(){
|
||||||
|
|
||||||
|
describe("execute", function(){
|
||||||
|
|
||||||
|
it("should add `securities` to the oriAction call", function(){
|
||||||
|
// Given
|
||||||
|
const system = {
|
||||||
|
getSystem: () => system,
|
||||||
|
specSelectors: {
|
||||||
|
specJson: () => fromJS({
|
||||||
|
openapi: "3.0.0"
|
||||||
|
}),
|
||||||
|
securityDefinitions: () => {
|
||||||
|
return fromJS({
|
||||||
|
"oauth2AuthorizationCode": {
|
||||||
|
"type": "oauth2",
|
||||||
|
"flows": {
|
||||||
|
"authorizationCode": {
|
||||||
|
"authorizationUrl": "http://google.com/",
|
||||||
|
"tokenUrl": "http://google.com/",
|
||||||
|
"scopes": {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth2Multiflow": {
|
||||||
|
"type": "oauth2",
|
||||||
|
"flows": {
|
||||||
|
"clientCredentials": {
|
||||||
|
"tokenUrl": "http://google.com/",
|
||||||
|
"scopes": {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"tokenUrl": "http://google.com/",
|
||||||
|
"scopes": {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"authorizationCode": {
|
||||||
|
"authorizationUrl": "http://google.com/",
|
||||||
|
"tokenUrl": "http://google.com/",
|
||||||
|
"scopes": {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When
|
||||||
|
let res = definitionsToAuthorize(() => null, system)()
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(res.toJS()).toEqual([
|
||||||
|
{
|
||||||
|
oauth2AuthorizationCode: {
|
||||||
|
flow: "authorizationCode",
|
||||||
|
authorizationUrl: "http://google.com/",
|
||||||
|
tokenUrl: "http://google.com/",
|
||||||
|
scopes: {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
},
|
||||||
|
type: "oauth2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
oauth2Multiflow: {
|
||||||
|
flow: "clientCredentials",
|
||||||
|
tokenUrl: "http://google.com/",
|
||||||
|
scopes: {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
},
|
||||||
|
type: "oauth2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
oauth2Multiflow: {
|
||||||
|
flow: "password",
|
||||||
|
tokenUrl: "http://google.com/",
|
||||||
|
scopes: {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
},
|
||||||
|
type: "oauth2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
oauth2Multiflow: {
|
||||||
|
flow: "authorizationCode",
|
||||||
|
authorizationUrl: "http://google.com/",
|
||||||
|
tokenUrl: "http://google.com/",
|
||||||
|
scopes: {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
},
|
||||||
|
type: "oauth2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
@@ -16,7 +16,8 @@ import {
|
|||||||
fromJSOrdered,
|
fromJSOrdered,
|
||||||
getAcceptControllingResponse,
|
getAcceptControllingResponse,
|
||||||
createDeepLinkPath,
|
createDeepLinkPath,
|
||||||
escapeDeepLinkPath
|
escapeDeepLinkPath,
|
||||||
|
sanitizeUrl
|
||||||
} from "core/utils"
|
} from "core/utils"
|
||||||
import win from "core/window"
|
import win from "core/window"
|
||||||
|
|
||||||
@@ -277,461 +278,438 @@ describe("utils", function() {
|
|||||||
let param = null
|
let param = null
|
||||||
let result = null
|
let result = null
|
||||||
|
|
||||||
it("skips validation when `type` is not specified", function() {
|
const assertValidateParam = (param, expectedError) => {
|
||||||
// invalid type
|
// Swagger 2.0 version
|
||||||
|
result = validateParam( fromJS(param), false )
|
||||||
|
expect( result ).toEqual( expectedError )
|
||||||
|
|
||||||
|
// OAS3 version, using `schema` sub-object
|
||||||
|
let oas3Param = {
|
||||||
|
value: param.value,
|
||||||
|
required: param.required,
|
||||||
|
schema: {
|
||||||
|
...param,
|
||||||
|
value: undefined,
|
||||||
|
required: undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = validateParam( fromJS(oas3Param), false, true )
|
||||||
|
expect( result ).toEqual( expectedError )
|
||||||
|
}
|
||||||
|
|
||||||
|
it("should check the isOAS3 flag when validating parameters", function() {
|
||||||
|
// This should "skip" validation because there is no `schema.type` property
|
||||||
|
// and we are telling `validateParam` this is an OAS3 spec
|
||||||
param = fromJS({
|
param = fromJS({
|
||||||
required: false,
|
value: "",
|
||||||
type: undefined,
|
required: true,
|
||||||
value: ""
|
schema: {
|
||||||
|
notTheTypeProperty: "string"
|
||||||
|
}
|
||||||
})
|
})
|
||||||
result = validateParam( param, false )
|
result = validateParam( param, false, true )
|
||||||
expect( result ).toEqual( [] )
|
expect( result ).toEqual( [] )
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates required strings", function() {
|
it("validates required strings", function() {
|
||||||
// invalid string
|
// invalid string
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "string",
|
type: "string",
|
||||||
value: ""
|
value: ""
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Required field is not provided"])
|
||||||
expect( result ).toEqual( ["Required field is not provided"] )
|
|
||||||
|
|
||||||
// valid string
|
// valid string
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "string",
|
type: "string",
|
||||||
value: "test string"
|
value: "test string"
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
|
|
||||||
// valid string with min and max length
|
// valid string with min and max length
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "string",
|
type: "string",
|
||||||
value: "test string",
|
value: "test string",
|
||||||
maxLength: 50,
|
maxLength: 50,
|
||||||
minLength: 1
|
minLength: 1
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates required strings with min and max length", function() {
|
it("validates required strings with min and max length", function() {
|
||||||
// invalid string with max length
|
// invalid string with max length
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "string",
|
type: "string",
|
||||||
value: "test string",
|
value: "test string",
|
||||||
maxLength: 5
|
maxLength: 5
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Value must be less than MaxLength"])
|
||||||
expect( result ).toEqual( ["Value must be less than MaxLength"] )
|
|
||||||
|
|
||||||
// invalid string with max length 0
|
// invalid string with max length 0
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "string",
|
type: "string",
|
||||||
value: "test string",
|
value: "test string",
|
||||||
maxLength: 0
|
maxLength: 0
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Value must be less than MaxLength"])
|
||||||
expect( result ).toEqual( ["Value must be less than MaxLength"] )
|
|
||||||
|
|
||||||
|
|
||||||
// invalid string with min length
|
// invalid string with min length
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "string",
|
type: "string",
|
||||||
value: "test string",
|
value: "test string",
|
||||||
minLength: 50
|
minLength: 50
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Value must be greater than MinLength"])
|
||||||
expect( result ).toEqual( ["Value must be greater than MinLength"] )
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates optional strings", function() {
|
it("validates optional strings", function() {
|
||||||
// valid (empty) string
|
// valid (empty) string
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "string",
|
type: "string",
|
||||||
value: ""
|
value: ""
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
|
|
||||||
// valid string
|
// valid string
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "string",
|
type: "string",
|
||||||
value: "test"
|
value: "test"
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates required files", function() {
|
it("validates required files", function() {
|
||||||
// invalid file
|
// invalid file
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "file",
|
type: "file",
|
||||||
value: undefined
|
value: undefined
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Required field is not provided"])
|
||||||
expect( result ).toEqual( ["Required field is not provided"] )
|
|
||||||
|
|
||||||
// valid file
|
// valid file
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "file",
|
type: "file",
|
||||||
value: new win.File()
|
value: new win.File()
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates optional files", function() {
|
it("validates optional files", function() {
|
||||||
// invalid file
|
// invalid file
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "file",
|
type: "file",
|
||||||
value: "not a file"
|
value: "not a file"
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Value must be a file"])
|
||||||
expect( result ).toEqual( ["Value must be a file"] )
|
|
||||||
|
|
||||||
// valid (empty) file
|
// valid (empty) file
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "file",
|
type: "file",
|
||||||
value: undefined
|
value: undefined
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
|
|
||||||
// valid file
|
// valid file
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "file",
|
type: "file",
|
||||||
value: new win.File()
|
value: new win.File()
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates required arrays", function() {
|
it("validates required arrays", function() {
|
||||||
// invalid (empty) array
|
// invalid (empty) array
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "array",
|
type: "array",
|
||||||
value: []
|
value: []
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Required field is not provided"])
|
||||||
expect( result ).toEqual( ["Required field is not provided"] )
|
|
||||||
|
|
||||||
// invalid (not an array)
|
// invalid (not an array)
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "array",
|
type: "array",
|
||||||
value: undefined
|
value: undefined
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Required field is not provided"])
|
||||||
expect( result ).toEqual( ["Required field is not provided"] )
|
|
||||||
|
|
||||||
// invalid array, items do not match correct type
|
// invalid array, items do not match correct type
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "array",
|
type: "array",
|
||||||
value: [1],
|
value: [1],
|
||||||
items: {
|
items: {
|
||||||
type: "string"
|
type: "string"
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [{index: 0, error: "Value must be a string"}])
|
||||||
expect( result ).toEqual( [{index: 0, error: "Value must be a string"}] )
|
|
||||||
|
|
||||||
// valid array, with no 'type' for items
|
// valid array, with no 'type' for items
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "array",
|
type: "array",
|
||||||
value: ["1"]
|
value: ["1"]
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
|
|
||||||
// valid array, items match type
|
// valid array, items match type
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "array",
|
type: "array",
|
||||||
value: ["1"],
|
value: ["1"],
|
||||||
items: {
|
items: {
|
||||||
type: "string"
|
type: "string"
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates optional arrays", function() {
|
it("validates optional arrays", function() {
|
||||||
// valid, empty array
|
// valid, empty array
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "array",
|
type: "array",
|
||||||
value: []
|
value: []
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
|
|
||||||
// invalid, items do not match correct type
|
// invalid, items do not match correct type
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "array",
|
type: "array",
|
||||||
value: ["number"],
|
value: ["number"],
|
||||||
items: {
|
items: {
|
||||||
type: "number"
|
type: "number"
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [{index: 0, error: "Value must be a number"}])
|
||||||
expect( result ).toEqual( [{index: 0, error: "Value must be a number"}] )
|
|
||||||
|
|
||||||
// valid
|
// valid
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "array",
|
type: "array",
|
||||||
value: ["test"],
|
value: ["test"],
|
||||||
items: {
|
items: {
|
||||||
type: "string"
|
type: "string"
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates required booleans", function() {
|
it("validates required booleans", function() {
|
||||||
// invalid boolean value
|
// invalid boolean value
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: undefined
|
value: undefined
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Required field is not provided"])
|
||||||
expect( result ).toEqual( ["Required field is not provided"] )
|
|
||||||
|
|
||||||
// invalid boolean value (not a boolean)
|
// invalid boolean value (not a boolean)
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: "test string"
|
value: "test string"
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Required field is not provided"])
|
||||||
expect( result ).toEqual( ["Required field is not provided"] )
|
|
||||||
|
|
||||||
// valid boolean value
|
// valid boolean value
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: "true"
|
value: "true"
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
|
|
||||||
// valid boolean value
|
// valid boolean value
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: false
|
value: false
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates optional booleans", function() {
|
it("validates optional booleans", function() {
|
||||||
// valid (empty) boolean value
|
// valid (empty) boolean value
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: undefined
|
value: undefined
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
|
|
||||||
// invalid boolean value (not a boolean)
|
// invalid boolean value (not a boolean)
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: "test string"
|
value: "test string"
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Value must be a boolean"])
|
||||||
expect( result ).toEqual( ["Value must be a boolean"] )
|
|
||||||
|
|
||||||
// valid boolean value
|
// valid boolean value
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: "true"
|
value: "true"
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
|
|
||||||
// valid boolean value
|
// valid boolean value
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: false
|
value: false
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates required numbers", function() {
|
it("validates required numbers", function() {
|
||||||
// invalid number, string instead of a number
|
// invalid number, string instead of a number
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "number",
|
type: "number",
|
||||||
value: "test"
|
value: "test"
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Required field is not provided"])
|
||||||
expect( result ).toEqual( ["Required field is not provided"] )
|
|
||||||
|
|
||||||
// invalid number, undefined value
|
// invalid number, undefined value
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "number",
|
type: "number",
|
||||||
value: undefined
|
value: undefined
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Required field is not provided"])
|
||||||
expect( result ).toEqual( ["Required field is not provided"] )
|
|
||||||
|
|
||||||
// valid number with min and max
|
// valid number with min and max
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "number",
|
type: "number",
|
||||||
value: 10,
|
value: 10,
|
||||||
minimum: 5,
|
minimum: 5,
|
||||||
maximum: 99
|
maximum: 99
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
|
|
||||||
// valid negative number with min and max
|
// valid negative number with min and max
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "number",
|
type: "number",
|
||||||
value: -10,
|
value: -10,
|
||||||
minimum: -50,
|
minimum: -50,
|
||||||
maximum: -5
|
maximum: -5
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
|
|
||||||
// invalid number with maximum:0
|
// invalid number with maximum:0
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "number",
|
type: "number",
|
||||||
value: 1,
|
value: 1,
|
||||||
maximum: 0
|
maximum: 0
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Value must be less than Maximum"])
|
||||||
expect( result ).toEqual( ["Value must be less than Maximum"] )
|
|
||||||
|
|
||||||
// invalid number with minimum:0
|
// invalid number with minimum:0
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "number",
|
type: "number",
|
||||||
value: -10,
|
value: -10,
|
||||||
minimum: 0
|
minimum: 0
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Value must be greater than Minimum"])
|
||||||
expect( result ).toEqual( ["Value must be greater than Minimum"] )
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates optional numbers", function() {
|
it("validates optional numbers", function() {
|
||||||
// invalid number, string instead of a number
|
// invalid number, string instead of a number
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "number",
|
type: "number",
|
||||||
value: "test"
|
value: "test"
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Value must be a number"])
|
||||||
expect( result ).toEqual( ["Value must be a number"] )
|
|
||||||
|
|
||||||
// valid (empty) number
|
// valid (empty) number
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "number",
|
type: "number",
|
||||||
value: undefined
|
value: undefined
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
|
|
||||||
// valid number
|
// valid number
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "number",
|
type: "number",
|
||||||
value: 10
|
value: 10
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates required integers", function() {
|
it("validates required integers", function() {
|
||||||
// invalid integer, string instead of an integer
|
// invalid integer, string instead of an integer
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "integer",
|
type: "integer",
|
||||||
value: "test"
|
value: "test"
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Required field is not provided"])
|
||||||
expect( result ).toEqual( ["Required field is not provided"] )
|
|
||||||
|
|
||||||
// invalid integer, undefined value
|
// invalid integer, undefined value
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "integer",
|
type: "integer",
|
||||||
value: undefined
|
value: undefined
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Required field is not provided"])
|
||||||
expect( result ).toEqual( ["Required field is not provided"] )
|
|
||||||
|
|
||||||
// valid integer
|
// valid integer
|
||||||
param = fromJS({
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
type: "integer",
|
type: "integer",
|
||||||
value: 10
|
value: 10
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates optional integers", function() {
|
it("validates optional integers", function() {
|
||||||
// invalid integer, string instead of an integer
|
// invalid integer, string instead of an integer
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "integer",
|
type: "integer",
|
||||||
value: "test"
|
value: "test"
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, ["Value must be an integer"])
|
||||||
expect( result ).toEqual( ["Value must be an integer"] )
|
|
||||||
|
|
||||||
// valid (empty) integer
|
// valid (empty) integer
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "integer",
|
type: "integer",
|
||||||
value: undefined
|
value: undefined
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
|
|
||||||
// integers
|
// integers
|
||||||
param = fromJS({
|
param = {
|
||||||
required: false,
|
required: false,
|
||||||
type: "integer",
|
type: "integer",
|
||||||
value: 10
|
value: 10
|
||||||
})
|
}
|
||||||
result = validateParam( param, false )
|
assertValidateParam(param, [])
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -908,4 +886,43 @@ describe("utils", function() {
|
|||||||
expect(result).toEqual("hello\\#world")
|
expect(result).toEqual("hello\\#world")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("sanitizeUrl", function() {
|
||||||
|
it("should sanitize a `javascript:` url", function() {
|
||||||
|
const res = sanitizeUrl("javascript:alert('bam!')")
|
||||||
|
|
||||||
|
expect(res).toEqual("about:blank")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should sanitize a `data:` url", function() {
|
||||||
|
const res = sanitizeUrl(`data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGV
|
||||||
|
sbG8iKTs8L3NjcmlwdD4=`)
|
||||||
|
|
||||||
|
expect(res).toEqual("about:blank")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should not modify a `http:` url", function() {
|
||||||
|
const res = sanitizeUrl(`http://swagger.io/`)
|
||||||
|
|
||||||
|
expect(res).toEqual("http://swagger.io/")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should not modify a `https:` url", function() {
|
||||||
|
const res = sanitizeUrl(`https://swagger.io/`)
|
||||||
|
|
||||||
|
expect(res).toEqual("https://swagger.io/")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should gracefully handle empty strings", function() {
|
||||||
|
expect(sanitizeUrl("")).toEqual("")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should gracefully handle non-string values", function() {
|
||||||
|
expect(sanitizeUrl(123)).toEqual("")
|
||||||
|
expect(sanitizeUrl(null)).toEqual("")
|
||||||
|
expect(sanitizeUrl(undefined)).toEqual("")
|
||||||
|
expect(sanitizeUrl([])).toEqual("")
|
||||||
|
expect(sanitizeUrl({})).toEqual("")
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ let rules = [
|
|||||||
name: "[name].js"
|
name: "[name].js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ loader: "babel-loader" }
|
{ loader: "babel-loader?retainLines=true" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ let rules = [
|
|||||||
name: "[name].js"
|
name: "[name].js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ loader: "babel-loader" }
|
{ loader: "babel-loader?retainLines=true" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ let rules = [
|
|||||||
name: "[name].js"
|
name: "[name].js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ loader: "babel-loader" }
|
{ loader: "babel-loader?retainLines=true" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -9,13 +9,7 @@ const rules = [
|
|||||||
inline: true
|
inline: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ loader: "babel-loader" }
|
{ loader: "babel-loader?retainLines=true" }
|
||||||
]
|
|
||||||
},
|
|
||||||
{ test: /\.(jsx)(\?.*)?$/,
|
|
||||||
use: [
|
|
||||||
{ loader: "react-hot-loader" },
|
|
||||||
{ loader: "babel-loader" }
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ test: /\.(css)(\?.*)?$/,
|
{ test: /\.(css)(\?.*)?$/,
|
||||||
@@ -48,7 +42,7 @@ module.exports = require("./make-webpack-config")(rules, {
|
|||||||
_special: {
|
_special: {
|
||||||
separateStylesheets: false,
|
separateStylesheets: false,
|
||||||
},
|
},
|
||||||
devtool: "eval",
|
devtool: "eval-source-map",
|
||||||
entry: {
|
entry: {
|
||||||
"swagger-ui-bundle": [
|
"swagger-ui-bundle": [
|
||||||
"./src/polyfills",
|
"./src/polyfills",
|
||||||
|
|||||||
Reference in New Issue
Block a user