Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e74989f22e | ||
|
|
73ed923e28 | ||
|
|
599b448f91 | ||
|
|
6e40d04741 | ||
|
|
e80b2f5b3f | ||
|
|
32cd6fe09c | ||
|
|
8aebea34c4 | ||
|
|
5f6320e754 | ||
|
|
5574a6cb1f | ||
|
|
bb2e75da8f | ||
|
|
ee3669312a | ||
|
|
c81f51f696 | ||
|
|
e2003ae922 | ||
|
|
0ac0b5ba32 | ||
|
|
f8381bf907 | ||
|
|
d378d38c12 | ||
|
|
53986d60bc | ||
|
|
5b6f27c7db | ||
|
|
47b495b24d | ||
|
|
496062f980 | ||
|
|
a920e3ab69 | ||
|
|
14e9fd7b0f | ||
|
|
ac4ef3fdd4 | ||
|
|
2de7b957df | ||
|
|
a068f78252 | ||
|
|
933da1e93a | ||
|
|
3c1a1780a6 | ||
|
|
bf1bc120fe | ||
|
|
fce31afa6c | ||
|
|
b73063578c | ||
|
|
cbd74b0c67 | ||
|
|
8e80ca9583 | ||
|
|
3ef50589e9 | ||
|
|
1d146394f3 | ||
|
|
e91573af39 | ||
|
|
2cc3e3c2d6 | ||
|
|
af7a99e901 | ||
|
|
7e1eb4e9a7 | ||
|
|
4f0cf53401 | ||
|
|
073eff4e10 | ||
|
|
cd7007d557 | ||
|
|
b76dcc2d4a | ||
|
|
b2af309cd5 | ||
|
|
7296a054c4 | ||
|
|
6b5063ead1 | ||
|
|
018491b4a7 | ||
|
|
74b4a3d598 | ||
|
|
51b04b3a26 |
+1
-1
@@ -2,5 +2,5 @@ node_modules
|
||||
.idea
|
||||
.deps_check
|
||||
.DS_Store
|
||||
npm-debug.log
|
||||
npm-debug.log*
|
||||
.eslintcache
|
||||
|
||||
@@ -15,7 +15,7 @@ The OpenAPI Specification has undergone 4 revisions since initial creation in 20
|
||||
|
||||
Swagger UI Version | Release Date | OpenAPI Spec compatibility | Notes | Status
|
||||
------------------ | ------------ | -------------------------- | ----- | ------
|
||||
3.0.8 | 2017-03-19 | 2.0 | [tag v3.0.8](https://github.com/swagger-api/swagger-ui/tree/v3.0.8) |
|
||||
3.0.10 | 2017-03-19 | 2.0 | [tag v3.0.10](https://github.com/swagger-api/swagger-ui/tree/v3.0.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.0.24 | 2014-09-12 | 1.1, 1.2 | [tag v2.0.24](https://github.com/swagger-api/swagger-ui/tree/v2.0.24) |
|
||||
@@ -75,6 +75,33 @@ To use swagger-ui's bundles, you should take a look at the [source of swagger-ui
|
||||
})
|
||||
```
|
||||
|
||||
#### OAuth2 configuration
|
||||
You can configure OAuth2 authorization by calling `initOAuth` method with passed configs under the instance of `SwaggerUIBundle`
|
||||
default `client_id` and `client_secret`, `realm`, an application name `appName`, `scopeSeparator`, `additionalQueryStringParams`.
|
||||
|
||||
Config Name | Description
|
||||
--- | ---
|
||||
client_id | Default clientId. MUST be a string
|
||||
client_secret | Default clientSecret. MUST be a string
|
||||
realm | realm query parameter (for oauth1) added to `authorizationUrl` and `tokenUrl` . MUST be a string
|
||||
appName | application name, displayed in authorization popup. MUST be a string
|
||||
scopeSeparator | scope separator for passing scopes, encoded before calling, default value is a space (encoded value `%20`). MUST be a string
|
||||
additionalQueryStringParams | Additional query parameters added to `authorizationUrl` and `tokenUrl`. MUST be an object
|
||||
|
||||
```
|
||||
const ui = SwaggerUIBundle({...})
|
||||
|
||||
// Method can be called in any place after calling constructor SwaggerUIBundle
|
||||
ui.initOAuth({
|
||||
clientId: "your-client-id",
|
||||
clientSecret: "your-client-secret-if-required",
|
||||
realm: "your-realms",
|
||||
appName: "your-app-name",
|
||||
scopeSeparator: " ",
|
||||
additionalQueryStringParams: {test: "hello"}
|
||||
})
|
||||
```
|
||||
|
||||
If you'd like to use the bundle files via npm, check out the [`swagger-ui-dist` package](https://www.npmjs.com/package/swagger-ui-dist).
|
||||
|
||||
#### Parameters
|
||||
@@ -87,8 +114,34 @@ validatorUrl | By default, Swagger-UI attempts to validate specs against swagger
|
||||
dom_id | The id of a dom element inside which SwaggerUi will put the user interface for swagger.
|
||||
oauth2RedirectUrl | OAuth redirect URL
|
||||
operationsSorter | Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), 'method' (sort by HTTP method) or a function (see Array.prototype.sort() to know how sort function works). Default is the order returned by the server unchanged.
|
||||
configUrl | Configs URL
|
||||
|
||||
### Plugins
|
||||
|
||||
#### Topbar plugin
|
||||
Topbar plugin enables top bar with input for spec path and explore button. By default the plugin is enabled, and to disable it you need to remove Topbar plugin from presets in `src/standalone/index.js`:
|
||||
|
||||
```
|
||||
let preset = [
|
||||
// TopbarPlugin,
|
||||
ConfigsPlugin,
|
||||
() => {
|
||||
return {
|
||||
components: { StandaloneLayout }
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
#### Configs plugin
|
||||
Configs plugin allows to fetch external configs instead of passing them to `SwaggerUIBundle`. Fetched configs support two formats: JSON or yaml. The plugin is enabled by default.
|
||||
There are three options of passing config:
|
||||
- add a query parameter `config` with URL to a server where the configs are hosted. For ex. http://petstore.swagger.io/?configs=http://localhost:3001/config.yaml
|
||||
- add a config `configUrl` with URL to SwaggerUIBundle
|
||||
- change default configs in `swagger-config.yaml` *Note: after changing, the project must be re-built*
|
||||
|
||||
These options can be used altogether, the order of inheritance is following (from the lowest priority to the highest):
|
||||
`swagger-config.yaml` -> config passed to `SwaggerUIBundle` -> config fetched from `configUrl` passed to `SwaggerUIBundle` -> config fetched from URL passed as a query parameter `config`
|
||||
|
||||
## CORS Support
|
||||
|
||||
|
||||
@@ -88,6 +88,15 @@ window.onload = function() {
|
||||
})
|
||||
|
||||
window.ui = ui
|
||||
|
||||
ui.initOAuth({
|
||||
clientId: "your-client-id",
|
||||
clientSecret: "your-client-secret-if-required",
|
||||
realm: "your-realms",
|
||||
appName: "your-app-name",
|
||||
scopeSeparator: "-",
|
||||
additionalQueryStringParams: {test: "hello"}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<!doctype html>
|
||||
<html lang="en-US">
|
||||
<body onload="run()">
|
||||
</body>
|
||||
</html>
|
||||
<script>
|
||||
'use strict';
|
||||
function run () {
|
||||
var oauth2 = window.opener.swaggerUIRedirectOauth2;
|
||||
var sentState = oauth2.state;
|
||||
var isValid, qp, arr;
|
||||
|
||||
qp = (window.location.hash || location.search).substring(1);
|
||||
|
||||
arr = qp.split("&")
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
|
||||
qp = qp ? JSON.parse('{' + arr.join() + '}',
|
||||
function (key, value) {
|
||||
return key === "" ? value : decodeURIComponent(value)
|
||||
}
|
||||
) : {}
|
||||
|
||||
isValid = qp.state === sentState
|
||||
|
||||
if (oauth2.auth.schema.get("flow") === "accessCode" && !oauth2.auth.code) {
|
||||
if (!isValid) {
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "warning",
|
||||
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
|
||||
});
|
||||
}
|
||||
|
||||
if (qp.code) {
|
||||
delete oauth2.state;
|
||||
oauth2.auth.code = qp.code;
|
||||
oauth2.callback(oauth2.auth);
|
||||
} else {
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "error",
|
||||
message: "Authorization failed: no accessCode received from the server"
|
||||
});
|
||||
}
|
||||
} else {
|
||||
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid});
|
||||
}
|
||||
window.close();
|
||||
}
|
||||
|
||||
</script>
|
||||
Vendored
+42
-42
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;AAu/FA;AA6+FA;;;;;;;;;;;;;;;;;;;;;;;;;;AAmTA;;;;;;AAoIA;AAi7FA;AAmtCA;AAi0IA;AA2pJA;AA+uFA;AA2rGA;AAgiFA;AA0rFA;AAk9CA;AA2hDA;AA4rCA;AAi6EA;;;;;AA2gCA;AA02JA;;;;;;;;;;;;;;AAuyEA;AA4mIA;AAquJA;AAwsHA;AA2mGA;AAiiEA;AAq4DA;AA+2DA;AAqlBA;;;;;;AAilFA;AAs1FA;;;;;AAy3CA;AA2qFA;AAw2CA;AAwkCA;AAs/CA;AA4kFA;AAy1FA;;;;;;;;;AAm5CA;AA2zIA;AAk4DA;AAolDA","sourceRoot":""}
|
||||
{"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;AAu/FA;AA6+FA;;;;;;;;;;;;;;;;;;;;;;;;;;AAyTA;;;;;;AAoIA;AAi7FA;AAmtCA;AAi0IA;AA0oJA;AAgwFA;AAmrGA;AA4lFA;AAioFA;AA09CA;AAwhDA;AAkrCA;AAu4EA;;;;;AAykCA;AAsyJA;;;;;;;;;;;;;;AA64EA;AA4mIA;AAquJA;AA2qHA;AA2mGA;AAiiEA;AAq4DA;AAg3DA;AAsdA;;;;;;AAgtFA;AA+4FA;;;;;AAw7CA;AA2qFA;AAw2CA;AAqkCA;AAq9CA;AAu/EA;AA83FA;;;;;;;;;AA+mDA;AA2zIA;AAk4DA;AA8mDA","sourceRoot":""}
|
||||
Vendored
+15
-3
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA4QA;AAitGA","sourceRoot":""}
|
||||
{"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA8QA;AAmvGA;AAuxFA;;;;;;AAocA;AAkvFA;AAu+CA;AAo+CA;AAgrCA;AAuyEA","sourceRoot":""}
|
||||
Vendored
+9
-9
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AAwxCA;AAoyHA;AAuxHA;AAy4FA;AA2sCA;AAmgCA;AA0iCA;AA+3BA","sourceRoot":""}
|
||||
{"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AA0yCA;AAoyHA;AA8xHA;AAokGA;AA+9BA;AA0hCA;AAmjCA;AA65BA","sourceRoot":""}
|
||||
+11
-1
@@ -9,7 +9,17 @@ const {gitDescribeSync} = require('git-describe');
|
||||
var loadersByExtension = require('./build-tools/loadersByExtension')
|
||||
|
||||
var pkg = require('./package.json')
|
||||
const gitInfo = gitDescribeSync(__dirname)
|
||||
|
||||
let gitInfo
|
||||
|
||||
try {
|
||||
gitInfo = gitDescribeSync(__dirname)
|
||||
} catch(e) {
|
||||
gitInfo = {
|
||||
hash: 'noGit',
|
||||
dirty: false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function(options) {
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "swagger-ui",
|
||||
"version": "3.0.8",
|
||||
"version": "3.0.10",
|
||||
"main": "dist/swagger-ui.js",
|
||||
"repository": "git@github.com:swagger-api/swagger-ui.git",
|
||||
"contributors": [
|
||||
@@ -69,7 +69,7 @@
|
||||
"reselect": "2.5.3",
|
||||
"serialize-error": "2.0.0",
|
||||
"shallowequal": "0.2.2",
|
||||
"swagger-client": "^3.0.8",
|
||||
"swagger-client": "~3.0.10",
|
||||
"url-parse": "^1.1.8",
|
||||
"whatwg-fetch": "0.11.1",
|
||||
"worker-loader": "^0.7.1",
|
||||
|
||||
@@ -21,14 +21,16 @@ export default class Oauth2 extends React.Component {
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context)
|
||||
let { name, schema, authorized } = this.props
|
||||
let { name, schema, authorized, authSelectors } = this.props
|
||||
let auth = authorized && authorized.get(name)
|
||||
let authConfigs = authSelectors.getConfigs() || {}
|
||||
let username = auth && auth.get("username") || ""
|
||||
let clientId = auth && auth.get("clientId") || ""
|
||||
let clientSecret = auth && auth.get("clientSecret") || ""
|
||||
let clientId = auth && auth.get("clientId") || authConfigs.clientId || ""
|
||||
let clientSecret = auth && auth.get("clientSecret") || authConfigs.clientSecret || ""
|
||||
let passwordType = auth && auth.get("passwordType") || "basic"
|
||||
|
||||
this.state = {
|
||||
appName: authConfigs.appName,
|
||||
name: name,
|
||||
schema: schema,
|
||||
scopes: [],
|
||||
@@ -41,11 +43,12 @@ export default class Oauth2 extends React.Component {
|
||||
}
|
||||
|
||||
authorize =() => {
|
||||
let { authActions, errActions, getConfigs } = this.props
|
||||
let { authActions, errActions, getConfigs, authSelectors } = this.props
|
||||
let configs = getConfigs()
|
||||
let authConfigs = authSelectors.getConfigs()
|
||||
|
||||
errActions.clear({authId: name,type: "auth", source: "auth"})
|
||||
oauth2Authorize(this.state, authActions, errActions, configs)
|
||||
oauth2Authorize({auth: this.state, authActions, errActions, configs, authConfigs })
|
||||
}
|
||||
|
||||
onScopeChange =(e) => {
|
||||
@@ -98,6 +101,7 @@ export default class Oauth2 extends React.Component {
|
||||
return (
|
||||
<div>
|
||||
<h4>OAuth2.0 <JumpToPath path={[ "securityDefinitions", name ]} /></h4>
|
||||
{ !this.state.appName ? null : <h5>Application: { this.state.appName } </h5> }
|
||||
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}}
|
||||
source={ schema.get("description") } />
|
||||
|
||||
@@ -153,7 +157,11 @@ export default class Oauth2 extends React.Component {
|
||||
{
|
||||
isAuthorized ? <code> ****** </code>
|
||||
: <Col tablet={10} desktop={10}>
|
||||
<input id="client_id" type="text" required={ flow === PASSWORD } data-name="clientId"
|
||||
<input id="client_id"
|
||||
type="text"
|
||||
required={ flow === PASSWORD }
|
||||
value={ this.state.clientId }
|
||||
data-name="clientId"
|
||||
onChange={ this.onInputChange }/>
|
||||
</Col>
|
||||
}
|
||||
@@ -166,7 +174,10 @@ export default class Oauth2 extends React.Component {
|
||||
{
|
||||
isAuthorized ? <code> ****** </code>
|
||||
: <Col tablet={10} desktop={10}>
|
||||
<input id="client_secret" type="text" data-name="clientSecret"
|
||||
<input id="client_secret"
|
||||
value={ this.state.clientSecret }
|
||||
type="text"
|
||||
data-name="clientSecret"
|
||||
onChange={ this.onInputChange }/>
|
||||
</Col>
|
||||
}
|
||||
@@ -182,11 +193,11 @@ export default class Oauth2 extends React.Component {
|
||||
<Row key={ name }>
|
||||
<div className="checkbox">
|
||||
<Input data-value={ name }
|
||||
id={`${name}-checkbox`}
|
||||
id={`${name}-checkbox-${this.state.name}`}
|
||||
disabled={ isAuthorized }
|
||||
type="checkbox"
|
||||
onChange={ this.onScopeChange }/>
|
||||
<label htmlFor={`${name}-checkbox`}>
|
||||
<label htmlFor={`${name}-checkbox-${this.state.name}`}>
|
||||
<span className="item"></span>
|
||||
<div className="text">
|
||||
<p className="name">{name}</p>
|
||||
|
||||
@@ -127,7 +127,7 @@ export const Input = (props) => <input {...props} />
|
||||
|
||||
export class Select extends React.Component {
|
||||
static propTypes = {
|
||||
allowedValues: PropTypes.object,
|
||||
allowedValues: PropTypes.array,
|
||||
value: PropTypes.any,
|
||||
onChange: PropTypes.func,
|
||||
multiple: PropTypes.bool,
|
||||
|
||||
@@ -28,11 +28,25 @@ export default class ParameterRow extends Component {
|
||||
|
||||
componentWillReceiveProps(props) {
|
||||
let { specSelectors, pathMethod, param } = props
|
||||
let example = param.get("example")
|
||||
let defaultValue = param.get("default")
|
||||
let parameter = specSelectors.getParameter(pathMethod, param.get("name"))
|
||||
let value = parameter ? parameter.get("value") : ""
|
||||
if ( defaultValue !== undefined && value === undefined ) {
|
||||
this.onChangeWrapper(defaultValue)
|
||||
let paramValue = parameter ? parameter.get("value") : undefined
|
||||
let enumValue = parameter ? parameter.get("enum") : undefined
|
||||
let value
|
||||
|
||||
if ( paramValue !== undefined ) {
|
||||
value = paramValue
|
||||
} else if ( example !== undefined ) {
|
||||
value = example
|
||||
} else if ( defaultValue !== undefined) {
|
||||
value = defaultValue
|
||||
} else if ( param.get("required") && enumValue && enumValue.size ) {
|
||||
value = enumValue.first()
|
||||
}
|
||||
|
||||
if ( value !== undefined ) {
|
||||
this.onChangeWrapper(value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
-7
@@ -1,19 +1,23 @@
|
||||
import deepExtend from "deep-extend"
|
||||
|
||||
import System from "core/system"
|
||||
import win from "core/window"
|
||||
import ApisPreset from "core/presets/apis"
|
||||
import * as AllPlugins from "core/plugins/all"
|
||||
import { filterConfigs } from "plugins/configs"
|
||||
import { parseSeach } from "core/utils"
|
||||
import { parseSeach, filterConfigs } from "core/utils"
|
||||
|
||||
const CONFIGS = [ "url", "spec", "validatorUrl", "onComplete", "onFailure", "authorizations", "docExpansion",
|
||||
"apisSorter", "operationsSorter", "supportedSubmitMethods", "highlightSizeThreshold", "dom_id",
|
||||
"defaultModelRendering", "oauth2RedirectUrl", "showRequestHeaders" ]
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
const { GIT_DIRTY, GIT_COMMIT, PACKAGE_VERSION } = buildInfo
|
||||
|
||||
window.versions = window.versions || {}
|
||||
window.versions.swaggerUi = `${PACKAGE_VERSION}/${GIT_COMMIT || "unknown"}${GIT_DIRTY ? "-dirty" : ""}`
|
||||
|
||||
module.exports = function SwaggerUI(opts) {
|
||||
|
||||
win.versions = win.versions || {}
|
||||
win.versions.swaggerUi = `${PACKAGE_VERSION}/${GIT_COMMIT || "unknown"}${GIT_DIRTY ? "-dirty" : ""}`
|
||||
|
||||
const defaults = {
|
||||
// Some general settings, that we floated to the top
|
||||
dom_id: null,
|
||||
@@ -74,14 +78,16 @@ module.exports = function SwaggerUI(opts) {
|
||||
var system = store.getSystem()
|
||||
let queryConfig = parseSeach()
|
||||
|
||||
system.initOAuth = system.authActions.configureAuth
|
||||
|
||||
const downloadSpec = (fetchedConfig) => {
|
||||
if(typeof constructorConfig !== "object") {
|
||||
return system
|
||||
}
|
||||
|
||||
let localConfig = system.specSelectors.getLocalConfig ? system.specSelectors.getLocalConfig() : {}
|
||||
let mergedConfig = deepExtend({}, constructorConfig, localConfig, fetchedConfig || {}, queryConfig)
|
||||
store.setConfigs(filterConfigs(mergedConfig))
|
||||
let mergedConfig = deepExtend({}, localConfig, constructorConfig, fetchedConfig || {}, queryConfig)
|
||||
store.setConfigs(filterConfigs(mergedConfig, CONFIGS))
|
||||
|
||||
if (fetchedConfig !== null) {
|
||||
if (!queryConfig.url && typeof mergedConfig.spec === "object" && Object.keys(mergedConfig.spec).length) {
|
||||
|
||||
@@ -69,7 +69,7 @@ export class JsonSchema_string extends Component {
|
||||
return <Input type="file" className={ errors.length ? "invalid" : ""} onChange={ this.onChange } disabled={isDisabled}/>
|
||||
}
|
||||
else {
|
||||
return <Input type="text" className={ errors.length ? "invalid" : ""} value={value} placeholder={description} onChange={ this.onChange } disabled={isDisabled}/>
|
||||
return <Input type={ schema.format === "password" ? "password" : "text" } className={ errors.length ? "invalid" : ""} value={value} placeholder={description} onChange={ this.onChange } disabled={isDisabled}/>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import win from "core/window"
|
||||
import { btoa } from "core/utils"
|
||||
|
||||
export default function authorize ( auth, authActions, errActions, configs ) {
|
||||
export default function authorize ( { auth, authActions, errActions, configs, authConfigs={} } ) {
|
||||
let { schema, scopes, name, clientId } = auth
|
||||
|
||||
let { additionalQueryStringParams } = authConfigs
|
||||
let redirectUrl = configs.oauth2RedirectUrl
|
||||
let scopeSeparator = " "
|
||||
let scopeSeparator = authConfigs.scopeSeparator || " "
|
||||
let state = btoa(new Date())
|
||||
let flow = schema.get("flow")
|
||||
let url
|
||||
@@ -36,10 +37,15 @@ export default function authorize ( auth, authActions, errActions, configs ) {
|
||||
}
|
||||
|
||||
url += "&redirect_uri=" + encodeURIComponent(redirectUrl)
|
||||
+ "&realm=" + encodeURIComponent(authConfigs.realm);
|
||||
+ "&scope=" + encodeURIComponent(scopes.join(scopeSeparator))
|
||||
+ "&state=" + encodeURIComponent(state)
|
||||
+ "&client_id=" + encodeURIComponent(clientId)
|
||||
|
||||
for (let key in additionalQueryStringParams) {
|
||||
url += "&" + key + "=" + encodeURIComponent(additionalQueryStringParams[key])
|
||||
}
|
||||
|
||||
// pass action authorizeOauth2 and authentication data through window
|
||||
// to authorize with oauth2
|
||||
win.swaggerUIRedirectOauth2 = {
|
||||
|
||||
@@ -7,6 +7,7 @@ export const LOGOUT = "logout"
|
||||
export const PRE_AUTHORIZE_OAUTH2 = "pre_authorize_oauth2"
|
||||
export const AUTHORIZE_OAUTH2 = "authorize_oauth2"
|
||||
export const VALIDATE = "validate"
|
||||
export const CONFIGURE_AUTH = "configure_auth"
|
||||
|
||||
const scopeSeparator = " "
|
||||
|
||||
@@ -117,8 +118,14 @@ export const authorizeAccessCode = ( auth ) => ( { authActions } ) => {
|
||||
|
||||
}
|
||||
|
||||
export const authorizeRequest = ( data ) => ( { fn, authActions, errActions } ) => {
|
||||
export const authorizeRequest = ( data ) => ( { fn, authActions, errActions, authSelectors } ) => {
|
||||
let { body, query={}, headers={}, name, url, auth } = data
|
||||
let { additionalQueryStringParams } = authSelectors.getConfigs() || {}
|
||||
let fetchUrl = url
|
||||
|
||||
for (let key in additionalQueryStringParams) {
|
||||
url += "&" + key + "=" + encodeURIComponent(additionalQueryStringParams[key])
|
||||
}
|
||||
|
||||
let _headers = Object.assign({
|
||||
"Accept":"application/json, text/plain, */*",
|
||||
@@ -127,7 +134,7 @@ export const authorizeRequest = ( data ) => ( { fn, authActions, errActions } )
|
||||
}, headers)
|
||||
|
||||
fn.fetch({
|
||||
url: url,
|
||||
url: fetchUrl,
|
||||
method: "post",
|
||||
headers: _headers,
|
||||
query: query,
|
||||
@@ -169,3 +176,10 @@ export const authorizeRequest = ( data ) => ( { fn, authActions, errActions } )
|
||||
message: err.message
|
||||
} ) })
|
||||
}
|
||||
|
||||
export function configureAuth(payload) {
|
||||
return {
|
||||
type: CONFIGURE_AUTH,
|
||||
payload: payload
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ import {
|
||||
SHOW_AUTH_POPUP,
|
||||
AUTHORIZE,
|
||||
AUTHORIZE_OAUTH2,
|
||||
LOGOUT
|
||||
LOGOUT,
|
||||
CONFIGURE_AUTH
|
||||
} from "./actions"
|
||||
|
||||
export default {
|
||||
@@ -57,5 +58,9 @@ export default {
|
||||
})
|
||||
|
||||
return state.set("authorized", result)
|
||||
},
|
||||
|
||||
[CONFIGURE_AUTH]: (state, { payload } ) =>{
|
||||
return state.set("configs", payload)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,3 +79,8 @@ export const isAuthorized = ( state, securities ) =>( { authSelectors } ) => {
|
||||
}).indexOf(false) === -1
|
||||
}).length
|
||||
}
|
||||
|
||||
export const getConfigs = createSelector(
|
||||
state,
|
||||
auth => auth.get( "configs" )
|
||||
)
|
||||
|
||||
@@ -186,16 +186,23 @@ export const logRequest = (req) => {
|
||||
// Actually fire the request via fn.execute
|
||||
// (For debugging) and ease of testing
|
||||
export const executeRequest = (req) => ({fn, specActions, specSelectors}) => {
|
||||
let { pathName, method } = req
|
||||
let { pathName, method, operation } = req
|
||||
|
||||
let op = operation.toJS()
|
||||
|
||||
// if url is relative, parseUrl makes it absolute by inferring from `window.location`
|
||||
req.contextUrl = parseUrl(specSelectors.url()).toString()
|
||||
|
||||
let parsedRequest = Object.assign({}, req)
|
||||
if ( pathName && method ) {
|
||||
parsedRequest.operationId = method.toLowerCase() + "-" + pathName
|
||||
|
||||
if(op && op.operationId) {
|
||||
req.operationId = op.operationId
|
||||
} else if(op && pathName && method) {
|
||||
req.operationId = fn.opId(op, pathName, method)
|
||||
}
|
||||
|
||||
let parsedRequest = Object.assign({}, req)
|
||||
parsedRequest = fn.buildRequest(parsedRequest)
|
||||
|
||||
specActions.setRequest(req.pathName, req.method, parsedRequest)
|
||||
|
||||
return fn.execute(req)
|
||||
|
||||
@@ -7,7 +7,8 @@ module.exports = function({ configs }) {
|
||||
buildRequest: Swagger.buildRequest,
|
||||
execute: Swagger.execute,
|
||||
resolve: Swagger.resolve,
|
||||
serializeRes: Swagger.serializeRes
|
||||
serializeRes: Swagger.serializeRes,
|
||||
opId: Swagger.helpers.opId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -577,3 +577,15 @@ export const buildFormData = (data) => {
|
||||
}
|
||||
return formArr.join("&")
|
||||
}
|
||||
|
||||
export const filterConfigs = (configs, allowed) => {
|
||||
let i, filteredConfigs = {}
|
||||
|
||||
for (i in configs) {
|
||||
if (allowed.indexOf(i) !== -1) {
|
||||
filteredConfigs[i] = configs[i]
|
||||
}
|
||||
}
|
||||
|
||||
return filteredConfigs
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import YAML from "js-yaml"
|
||||
import yamlConfig from "../../../swagger-config.yaml"
|
||||
|
||||
const CONFIGS = [ "url", "spec", "validatorUrl", "onComplete", "onFailure", "authorizations", "docExpansion",
|
||||
"apisSorter", "operationsSorter", "supportedSubmitMethods", "highlightSizeThreshold", "dom_id",
|
||||
"defaultModelRendering", "oauth2RedirectUrl", "showRequestHeaders" ]
|
||||
|
||||
const parseYamlConfig = (yaml, system) => {
|
||||
try {
|
||||
return YAML.safeLoad(yaml)
|
||||
@@ -58,16 +54,3 @@ export default function configPlugin (toolbox) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function filterConfigs (configs) {
|
||||
let i, filteredConfigs = {}
|
||||
|
||||
for (i in configs) {
|
||||
if (CONFIGS.indexOf(i) !== -1) {
|
||||
filteredConfigs[i] = configs[i]
|
||||
}
|
||||
}
|
||||
|
||||
return filteredConfigs
|
||||
}
|
||||
|
||||
@@ -19,9 +19,10 @@ export default class Topbar extends React.Component {
|
||||
this.setState({url: value})
|
||||
}
|
||||
|
||||
downloadUrl = () => {
|
||||
downloadUrl = (e) => {
|
||||
this.props.specActions.updateUrl(this.state.url)
|
||||
this.props.specActions.download(this.state.url)
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -2,11 +2,13 @@ import StandaloneLayout from "./layout"
|
||||
import "../style/main.scss"
|
||||
|
||||
import TopbarPlugin from "plugins/topbar"
|
||||
import ConfigsPlugin from "plugins/configs"
|
||||
|
||||
// the Standalone preset
|
||||
|
||||
let preset = [
|
||||
TopbarPlugin,
|
||||
ConfigsPlugin,
|
||||
() => {
|
||||
return {
|
||||
components: { StandaloneLayout }
|
||||
|
||||
Reference in New Issue
Block a user