Compare commits

...
48 Commits
Author SHA1 Message Date
shockey e74989f22e Merge pull request #3077 from shockey/v/3.0.10
v3.0.10
2017-05-14 01:26:49 -07:00
Kyle Shockey 73ed923e28 v3.0.10 2017-05-14 01:10:00 -07:00
Kyle Shockey 599b448f91 Revert "fixes #2922"
This reverts commit 496062f980.
2017-05-13 10:15:38 -07:00
Kyle Shockey 6e40d04741 take advantage of Swagger-Client opId improvements 2017-05-13 09:50:34 -07:00
Anna e80b2f5b3f Merge pull request #3074 from bodnia/issue-2897
Issue 2897
2017-05-12 00:23:21 +03:00
Anna Bodnia 32cd6fe09c readme for configuration of auth 2017-05-11 20:14:49 +03:00
Anna Bodnia 8aebea34c4 add configuration of auth: scope separator, client id, client secret, app name, reaml, additionalQueryParams 2017-05-11 16:30:30 +03:00
Anna 5f6320e754 Merge pull request #3071 from bodnia/fix-3031
fixes #3031
2017-05-11 14:42:32 +03:00
Anna Bodnia 5574a6cb1f fixes #3031 2017-05-11 14:38:34 +03:00
shockey bb2e75da8f Merge pull request #3068 from shockey/bug/3027-gitless-building
try/catch git describe call
2017-05-10 22:11:09 -07:00
shockey ee3669312a Merge branch 'master' into bug/3027-gitless-building 2017-05-10 22:05:36 -07:00
Kyle Shockey c81f51f696 try/catch git describe call, fixes building without git present 2017-05-10 22:03:04 -07:00
shockey e2003ae922 Merge pull request #3058 from jmendiara/fix/gitignore
gitignore all npm-debug logs
2017-05-10 13:37:15 -07:00
shockey 0ac0b5ba32 Merge branch 'master' into fix/gitignore 2017-05-10 13:32:45 -07:00
shockey f8381bf907 Merge pull request #3057 from jmendiara/fix/configLocation
Move filterConfigs to core
2017-05-10 11:12:43 -07:00
Javier Mendiara d378d38c12 Merge branch 'master' into fix/gitignore 2017-05-10 18:20:32 +02:00
Javier Mendiara Cañardo 53986d60bc Move filterConfigs to core
Fixes #3056
2017-05-10 18:17:37 +02:00
Anna 5b6f27c7db Merge pull request #3065 from bodnia/fix-2922
#Fixes 2922
2017-05-10 17:11:15 +03:00
Anna Bodnia 47b495b24d build 2017-05-10 17:04:36 +03:00
Anna Bodnia 496062f980 fixes #2922 2017-05-10 17:03:18 +03:00
Anna a920e3ab69 Merge pull request #3064 from bodnia/fix-3045
Fix 3045
2017-05-10 15:30:16 +03:00
Anna Bodnia 14e9fd7b0f built 2017-05-10 15:21:46 +03:00
Anna Bodnia ac4ef3fdd4 fixes #3045 order of configs inheratance 2017-05-10 15:20:32 +03:00
Javier Mendiara Cañardo 2de7b957df gitignore all npm-debug logs
Lot of npm-debugs files can be generated in devs computers, each one with a number suffix
ex:
```sh
npm-debug.log.213131231
npm-debug.log.213131231
npm-debug.log.213131231
```

Adding a wildcard prevents for accidental commits

_Official and default .gitignore for node in github.com: https://github.com/github/gitignore/blob/master/Node.gitignore#L4_
2017-05-09 15:14:14 +02:00
shockey a068f78252 Merge pull request #3043 from shockey/v/3.0.9
v3.0.9
2017-05-05 20:04:54 -07:00
Kyle Shockey 933da1e93a Dist rebuild 2017-05-05 19:56:41 -07:00
Kyle Shockey 3c1a1780a6 v3.0.9 as declared version 2017-05-05 19:51:46 -07:00
Ron bf1bc120fe Merge pull request #3039 from bodnia/config-readme
Readme for Topbar plugin, Configs plugin
2017-05-05 14:54:39 -07:00
Ron fce31afa6c Merge branch 'master' into config-readme 2017-05-05 14:41:46 -07:00
Anna b73063578c Merge pull request #3040 from bodnia/config-plugin-enable
enable configs plugin by default
2017-05-05 17:57:22 +03:00
Anna Bodnia cbd74b0c67 enable configs plugin by default 2017-05-05 17:50:22 +03:00
Anna Bodnia 8e80ca9583 Readme for Topbar plugin, Configs plugin 2017-05-05 17:45:40 +03:00
shockey 3ef50589e9 Merge pull request #3029 from shockey/rebuild
Rebuild dist
2017-05-04 11:09:39 -07:00
Kyle Shockey 1d146394f3 Rebuild dist 2017-05-04 10:57:42 -07:00
shockey e91573af39 Merge pull request #3017 from Minasokoni/searchbar-fix
preventDefault the searchbar
2017-05-04 10:42:38 -07:00
shockey 2cc3e3c2d6 Merge branch 'master' into searchbar-fix 2017-05-04 10:29:14 -07:00
Anna af7a99e901 Merge pull request #3026 from bodnia/fix-2841
fixes #2841
2017-05-04 17:37:38 +03:00
Anna Bodnia 7e1eb4e9a7 fix #2841 2017-05-04 17:18:47 +03:00
Anna 4f0cf53401 Merge pull request #2949 from stefangr/fix_oauth2_scope_checkbox_uniqueness
Make the oauth2 scope checkbox id more unique.
2017-05-04 11:01:13 +03:00
Stefan Grootscholten 073eff4e10 Make the checkbox id more unique.
If the swagger.json defines more than one oauth2 Security scheme with
matching scopes, the id of the scope checkboxes were not unique.
As a result the scope for a second security scheme could not be
selected.

By adding the security scheme name to the id, it becomes more unique.
2017-05-04 09:39:22 +02:00
Robert Barnwell cd7007d557 Merge branch 'master' into searchbar-fix 2017-05-03 14:17:32 -07:00
shockey b76dcc2d4a Merge pull request #3018 from shockey/bug/3016-window-guard
Version stamping updates
2017-05-02 12:43:13 -07:00
Kyle Shockey b2af309cd5 Rebuild dist 2017-05-02 12:24:09 -07:00
Kyle Shockey 7296a054c4 Fix #3016 2017-05-02 12:15:17 -07:00
Minasokoni 6b5063ead1 Merge branch 'searchbar-fix' of github.com:Minasokoni/swagger-ui into searchbar-fix 2017-05-02 11:02:24 -07:00
Minasokoni 018491b4a7 removed semicolon 2017-05-02 11:02:14 -07:00
Robert Barnwell 74b4a3d598 Merge branch 'master' into searchbar-fix 2017-05-02 10:40:31 -07:00
Minasokoni 51b04b3a26 preventDefault the form 2017-05-02 10:38:35 -07:00
27 changed files with 315 additions and 111 deletions
+1 -1
View File
@@ -2,5 +2,5 @@ node_modules
.idea
.deps_check
.DS_Store
npm-debug.log
npm-debug.log*
.eslintcache
+54 -1
View File
@@ -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
+9
View File
@@ -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>
+53
View File
@@ -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>
+42 -42
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -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":""}
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -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":""}
+9 -9
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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",
+20 -9
View File
@@ -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>
+1 -1
View File
@@ -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,
+17 -3
View File
@@ -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
View File
@@ -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) {
+1 -1
View File
@@ -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}/>
}
}
}
+8 -2
View File
@@ -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 = {
+16 -2
View File
@@ -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
}
}
+6 -1
View File
@@ -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)
}
}
+5
View File
@@ -79,3 +79,8 @@ export const isAuthorized = ( state, securities ) =>( { authSelectors } ) => {
}).indexOf(false) === -1
}).length
}
export const getConfigs = createSelector(
state,
auth => auth.get( "configs" )
)
+11 -4
View File
@@ -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)
+2 -1
View File
@@ -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
}
}
}
+12
View File
@@ -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
}
-17
View File
@@ -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
}
+2 -1
View File
@@ -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
View File
@@ -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 }