Compare commits

..
2 Commits
Author SHA1 Message Date
kyle 7049de6201 v3.14.0 (#4492)
* v3.14.0

* fix: simplify config fetch interceptor implementation

* add `loadRemoteConfig` flag to requests

* v3.14.0
2018-04-27 23:20:13 -07:00
kyle 8cef3adfe6 fix: path-item $ref operation metadata storage (#4489) 2018-04-27 10:29:33 -07:00
15 changed files with 54 additions and 200 deletions
+1 -1
View File
@@ -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.13.5 | 2018-04-20 | 2.0, 3.0 | [tag v3.13.5](https://github.com/swagger-api/swagger-ui/tree/v3.13.5) 3.14.0 | 2018-04-27 | 2.0, 3.0 | [tag v3.14.0](https://github.com/swagger-api/swagger-ui/tree/v3.14.0)
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)
-81
View File
@@ -1,81 +0,0 @@
openapi: "3.0.0"
info:
version: 1.0.0
title: Brentertainment OAuth2 Test Server
description: >
The server does not support CORS (yet?), so you need to take the strange step of disabling Same-Origin Policy in your browser.
[Here](https://www.thepolyglotdeveloper.com/2014/08/bypass-cors-errors-testing-apis-locally/) are some instructions.
license:
name: MIT
servers:
- url: http://brentertainment.com/oauth2/lockdin/
paths:
/resource:
get:
description: Protected resource
security:
- oauth2AuthorizationCode: ["resource"]
- oauth2Implicit: ["resource"]
- oauth2Password: ["resource"]
- oauth2ClientCredentials: ["resource"]
- oauth2Multiflow: ["resource"]
responses:
200:
description: the only response
content:
application/json:
schema:
type: array
items:
type: string
components:
securitySchemes:
oauth2AuthorizationCode:
type: oauth2
flows:
authorizationCode:
authorizationUrl: "http://brentertainment.com/oauth2/lockdin/authorize"
tokenUrl: "http://brentertainment.com/oauth2/lockdin/token"
scopes:
resource: our only scope
oauth2Implicit:
type: oauth2
flows:
implicit:
authorizationUrl: "http://brentertainment.com/oauth2/lockdin/authorize"
scopes:
resource: our only scope
oauth2Password:
type: oauth2
flows:
password:
tokenUrl: "http://brentertainment.com/oauth2/lockdin/token"
scopes:
resource: our only scope
oauth2ClientCredentials:
type: oauth2
flows:
clientCredentials:
tokenUrl: "http://brentertainment.com/oauth2/lockdin/token"
scopes:
resource: our only scope
oauth2Multiflow:
type: oauth2
flows:
clientCredentials:
tokenUrl: "http://brentertainment.com/oauth2/lockdin/token"
scopes:
resource: our only scope
password:
tokenUrl: "http://brentertainment.com/oauth2/lockdin/token"
scopes:
resource: our only scope
implicit:
authorizationUrl: "http://brentertainment.com/oauth2/lockdin/authorize"
scopes:
resource: our only scope
authorizationCode:
authorizationUrl: "http://brentertainment.com/oauth2/lockdin/authorize"
tokenUrl: "http://brentertainment.com/oauth2/lockdin/token"
scopes:
resource: our only scope
+14 -14
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "swagger-ui", "name": "swagger-ui",
"version": "3.13.6", "version": "3.14.0",
"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": [
+2 -5
View File
@@ -99,13 +99,10 @@ export default class Auths extends React.Component {
{ {
definitions.filter( schema => schema.get("type") === "oauth2") definitions.filter( schema => schema.get("type") === "oauth2")
.map( (schema, name) =>{ .map( (schema, name) =>{
const { flow } = schema return (<div key={ name }>
const key = [name, flow].join("__").slice(0, -2)
return (<div key={ key }>
<Oauth2 authorized={ authorized } <Oauth2 authorized={ authorized }
schema={ schema } schema={ schema }
authId={ key } name={ name } />
name={ key || schema.get("name") || name } />
</div>) </div>)
} }
).toArray() ).toArray()
+8 -8
View File
@@ -47,11 +47,11 @@ export default class Oauth2 extends React.Component {
} }
authorize =() => { authorize =() => {
let { authActions, errActions, getConfigs, authSelectors, authId } = this.props let { authActions, errActions, getConfigs, authSelectors } = this.props
let configs = getConfigs() let configs = getConfigs()
let authConfigs = authSelectors.getConfigs() let authConfigs = authSelectors.getConfigs()
errActions.clear({authId: authId ,type: "auth", source: "auth"}) errActions.clear({authId: name,type: "auth", source: "auth"})
oauth2Authorize({auth: this.state, authActions, errActions, configs, authConfigs }) oauth2Authorize({auth: this.state, authActions, errActions, configs, authConfigs })
} }
@@ -79,15 +79,15 @@ export default class Oauth2 extends React.Component {
logout =(e) => { logout =(e) => {
e.preventDefault() e.preventDefault()
let { authActions, errActions, authId } = this.props let { authActions, errActions, name } = this.props
errActions.clear({authId: authId, type: "auth", source: "auth"}) errActions.clear({authId: name, type: "auth", source: "auth"})
authActions.logout([ authId ]) authActions.logout([ name ])
} }
render() { render() {
let { let {
schema, getComponent, authSelectors, errSelectors, name, authId, specSelectors schema, getComponent, authSelectors, errSelectors, name, specSelectors
} = this.props } = this.props
const Input = getComponent("Input") const Input = getComponent("Input")
const Row = getComponent("Row") const Row = getComponent("Row")
@@ -107,9 +107,9 @@ export default class Oauth2 extends React.Component {
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(authId) let authorizedAuth = authSelectors.authorized().get(name)
let isAuthorized = !!authorizedAuth let isAuthorized = !!authorizedAuth
let errors = errSelectors.allErrors().filter( err => err.get("authId") === authId) let errors = errSelectors.allErrors().filter( err => err.get("authId") === name)
let isValid = !errors.filter( err => err.get("source") === "validation").size let isValid = !errors.filter( err => err.get("source") === "validation").size
let description = schema.get("description") let description = schema.get("description")
+6 -1
View File
@@ -173,7 +173,12 @@ module.exports = function SwaggerUI(opts) {
let configUrl = queryConfig.config || constructorConfig.configUrl let configUrl = queryConfig.config || constructorConfig.configUrl
if (!configUrl || !system.specActions.getConfigByUrl || system.specActions.getConfigByUrl && !system.specActions.getConfigByUrl(configUrl, downloadSpec)) { if (!configUrl || !system.specActions.getConfigByUrl || system.specActions.getConfigByUrl && !system.specActions.getConfigByUrl({
url: configUrl,
loadRemoteConfig: true,
requestInterceptor: constructorConfig.requestInterceptor,
responseInterceptor: constructorConfig.responseInterceptor,
}, downloadSpec)) {
return downloadSpec() return downloadSpec()
} }
+7 -16
View File
@@ -1,23 +1,14 @@
import { parseYamlConfig } from "./helpers" import { parseYamlConfig } from "./helpers"
export const downloadConfig = (url) => ({fn: { fetch }, getConfigs}) => { export const downloadConfig = (req) => (system) => {
const { requestInterceptor, responseInterceptor } = getConfigs() const {fn: { fetch }} = system
let req = { url }
if(requestInterceptor) {
req = requestInterceptor(req)
}
return fetch(req) return fetch(req)
.then(res => {
if(res) {
return responseInterceptor(res)
}
return res
})
} }
export const getConfigByUrl = (configUrl, cb)=> ({ specActions }) => { export const getConfigByUrl = (req, cb)=> ({ specActions }) => {
if (configUrl) { if (req) {
return specActions.downloadConfig(configUrl).then(next, next) return specActions.downloadConfig(req).then(next, next)
} }
function next(res) { function next(res) {
@@ -25,7 +16,7 @@ export const getConfigByUrl = (configUrl, cb)=> ({ specActions }) => {
specActions.updateLoadingStatus("failedConfig") specActions.updateLoadingStatus("failedConfig")
specActions.updateLoadingStatus("failedConfig") specActions.updateLoadingStatus("failedConfig")
specActions.updateUrl("") specActions.updateUrl("")
console.error(res.statusText + " " + configUrl) console.error(res.statusText + " " + req.url)
cb(null) cb(null)
} else { } else {
cb(parseYamlConfig(res.text)) cb(parseYamlConfig(res.text))
@@ -33,7 +33,6 @@ export const definitionsToAuthorize = onlyOAS3(createSelector(
definition.get("flows").entrySeq().forEach(([flowKey, flowVal]) => { definition.get("flows").entrySeq().forEach(([flowKey, flowVal]) => {
let translatedDef = fromJS({ let translatedDef = fromJS({
flow: flowKey, flow: flowKey,
name: defName,
authorizationUrl: flowVal.get("authorizationUrl"), authorizationUrl: flowVal.get("authorizationUrl"),
tokenUrl: flowVal.get("tokenUrl"), tokenUrl: flowVal.get("tokenUrl"),
scopes: flowVal.get("scopes"), scopes: flowVal.get("scopes"),
@@ -41,7 +40,7 @@ export const definitionsToAuthorize = onlyOAS3(createSelector(
}) })
list = list.push(new Map({ list = list.push(new Map({
[`${defName}__${flowKey}`]: translatedDef.filter((v) => { [defName]: translatedDef.filter((v) => {
// filter out unset values, sometimes `authorizationUrl` // filter out unset values, sometimes `authorizationUrl`
// and `tokenUrl` come out as `undefined` in the data // and `tokenUrl` come out as `undefined` in the data
return v !== undefined return v !== undefined
+7 -64
View File
@@ -5,80 +5,23 @@ import { downloadConfig } from "corePlugins/configs/spec-actions"
describe("configs plugin - actions", () => { describe("configs plugin - actions", () => {
describe("downloadConfig", () => { describe("downloadConfig", () => {
it("should call the system fetch helper with a provided url", () => { it("should call the system fetch helper with a provided request", () => {
const fetchSpy = createSpy(async () => {}).andCallThrough() const fetchSpy = createSpy(async () => {}).andCallThrough()
const system = { const system = {
fn: { fn: {
fetch: fetchSpy fetch: fetchSpy
},
getConfigs() {
return {}
} }
} }
const url = "http://swagger.io/one" const req = {
url: "http://swagger.io/one",
downloadConfig(url)(system) requestInterceptor: a => a,
responseInterceptor: a => a,
expect(fetchSpy).toHaveBeenCalledWith({
url: url
})
})
it("should allow the globally configured requestInterceptor to modify the request", () => {
const fetchSpy = createSpy(async () => {}).andCallThrough()
const requestInterceptorSpy = createSpy((req) => {
req.url = "http://swagger.io/two"
return req
}).andCallThrough()
const system = {
fn: {
fetch: fetchSpy
},
getConfigs() {
return {
requestInterceptor: requestInterceptorSpy
}
}
} }
const url = "http://swagger.io/one" downloadConfig(req)(system)
downloadConfig(url)(system) expect(fetchSpy).toHaveBeenCalledWith(req)
expect(fetchSpy).toHaveBeenCalledWith({
url: "http://swagger.io/two"
})
})
it("should allow the globally configured responseInterceptor to modify the response", async () => {
const fetchSpy = createSpy(async (req) => {
return {
url: req.url,
ok: true
}
}).andCallThrough()
const responseInterceptorSpy = createSpy((res) => {
res.url = "http://swagger.io/two"
return res
}).andCallThrough()
const system = {
fn: {
fetch: fetchSpy
},
getConfigs() {
return {
responseInterceptor: responseInterceptorSpy
}
}
}
const url = "http://swagger.io/one"
const res = await downloadConfig(url)(system)
expect(res).toEqual({
url: "http://swagger.io/two",
ok: true
})
}) })
}) })
}) })