From 559b315d0d997dba0ef14457e0c9de867a586a15 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Sun, 1 Oct 2017 10:30:41 -0600 Subject: [PATCH 1/8] Initial test for Markdown ` + const el = render() + expect(el.html()).toEqual(`

script

\n
`) + }) + }) + + describe("OAS 3", function() { + it("sanitizes ` + const el = render() + expect(el.html()).toEqual(`

script

`) + }) + }) +}) From 5a69603beb454a0d15002bfbd82902d9480e27b1 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Sun, 1 Oct 2017 13:59:28 -0600 Subject: [PATCH 2/8] Test for sanitizing elements. Test sanitization of the component --- test/xss/info-sanitization.js | 33 ++++++++++++++++++++++++ test/xss/markdown-script-sanitization.js | 12 +++++++++ 2 files changed, 45 insertions(+) create mode 100644 test/xss/info-sanitization.js diff --git a/test/xss/info-sanitization.js b/test/xss/info-sanitization.js new file mode 100644 index 00000000..6549aa11 --- /dev/null +++ b/test/xss/info-sanitization.js @@ -0,0 +1,33 @@ +/* eslint-env mocha */ +import React from "react" +import expect from "expect" +import { render } from "enzyme" +import { fromJS } from "immutable" +import Info from "components/info" +import Markdown from "components/providers/markdown" + +describe.only(" Sanitization", function(){ + const dummyComponent = () => null + const components = { + Markdown + } + const props = { + getComponent: c => components[c] || dummyComponent, + info: fromJS({ + title: "Test Title **strong** ", + description: "Description *with* " + }), + host: "example.test", + basePath: "/api" + } + + it("renders sanitized .title content", function(){ + let wrapper = render() + expect(wrapper.find(".title").html()).toEqual("Test Title **strong** <script>alert(1)</script>") + }) + + it("renders sanitized .description content", function() { + let wrapper = render() + expect(wrapper.find(".description").html()).toEqual("

Description with

\n
") + }) +}) diff --git a/test/xss/markdown-script-sanitization.js b/test/xss/markdown-script-sanitization.js index 4a353316..ef374dd7 100644 --- a/test/xss/markdown-script-sanitization.js +++ b/test/xss/markdown-script-sanitization.js @@ -12,6 +12,12 @@ describe.only("Markdown Script Sanitization", function() { const el = render() expect(el.html()).toEqual(`

script

\n
`) }) + + it("sanitizes elements", function() { + const str = `` + const el = render() + expect(el.html()).toEqual(`

\n
`) + }) }) describe("OAS 3", function() { @@ -20,5 +26,11 @@ describe.only("Markdown Script Sanitization", function() { const el = render() expect(el.html()).toEqual(`

script

`) }) + + it("sanitizes elements", function() { + const str = `` + const el = render() + expect(el.html()).toEqual(`
`) + }) }) }) From 729fd71546a156ebb66346f63078d9771c1bda8d Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Sun, 8 Oct 2017 09:09:29 -0600 Subject: [PATCH 3/8] Fixes #3734 Add

and

elements to sanitizer options. --- src/core/components/providers/markdown.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/components/providers/markdown.jsx b/src/core/components/providers/markdown.jsx index 2b21c10b..ef95c6ae 100644 --- a/src/core/components/providers/markdown.jsx +++ b/src/core/components/providers/markdown.jsx @@ -29,7 +29,7 @@ Markdown.propTypes = { export default Markdown const sanitizeOptions = { - allowedTags: sanitize.defaults.allowedTags.concat([ "img" ]), + allowedTags: sanitize.defaults.allowedTags.concat([ "h1", "h2", "img" ]), textFilter: function(text) { return text.replace(/"/g, "\"") } From ec76e512e2357e60795662ffb796ec293931c544 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Sun, 8 Oct 2017 09:38:08 -0600 Subject: [PATCH 4/8] Fixes #3730 Add extra check for missing response content and contentType --- src/core/components/response-body.jsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/components/response-body.jsx b/src/core/components/response-body.jsx index 265ff679..c55c1d6d 100644 --- a/src/core/components/response-body.jsx +++ b/src/core/components/response-body.jsx @@ -83,8 +83,12 @@ export default class ResponseBody extends React.Component { // Anything else (CORS) } else if (typeof content === "string") { bodyEl = - } else { + } else if ( content.size > 0 ) { + // We don't know the contentType, but there was some content returned bodyEl =
Unknown response type
+ } else { + // We don't know the contentType and there was no content returned + bodyEl = null } return ( !bodyEl ? null :
From 1785d48746274f7e6d9727b2edb7ae0920caaab0 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Sun, 8 Oct 2017 10:13:09 -0600 Subject: [PATCH 5/8] Remove .only from existing tests. Add markdown test cases for heading elements. --- test/components/markdown.js | 38 ++++++++++++++++++++++++ test/xss/info-sanitization.js | 2 +- test/xss/markdown-script-sanitization.js | 2 +- 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 test/components/markdown.js diff --git a/test/components/markdown.js b/test/components/markdown.js new file mode 100644 index 00000000..6dd87053 --- /dev/null +++ b/test/components/markdown.js @@ -0,0 +1,38 @@ +/* eslint-env mocha */ +import React from "react" +import expect from "expect" +import { render } from "enzyme" +import Markdown from "components/providers/markdown" +import { Markdown as OAS3Markdown } from "corePlugins/oas3/wrap-components/markdown.js" + +describe.only("Markdown component", function() { + describe("Swagger 2.0", function() { + it("allows heading elements", function() { + const str = ` +# h1 +## h2 +### h3 +#### h4 +##### h5 +###### h6 + ` + const el = render() + expect(el.html()).toEqual(`

h1

\n

h2

\n

h3

\n

h4

\n
h5
\n
h6
\n
`) + }) + }) + + describe("OAS 3", function() { + it("allows heading elements", function() { + const str = ` + # h1 + ## h2 + ### h3 + #### h4 + ##### h5 + ###### h6 + ` + const el = render() + expect(el.html()).toEqual(`

h1

\n

h2

\n

h3

\n

h4

\n
h5
\n
h6
`) + }) + }) +}) diff --git a/test/xss/info-sanitization.js b/test/xss/info-sanitization.js index 6549aa11..e868fe9f 100644 --- a/test/xss/info-sanitization.js +++ b/test/xss/info-sanitization.js @@ -6,7 +6,7 @@ import { fromJS } from "immutable" import Info from "components/info" import Markdown from "components/providers/markdown" -describe.only(" Sanitization", function(){ +describe(" Sanitization", function(){ const dummyComponent = () => null const components = { Markdown diff --git a/test/xss/markdown-script-sanitization.js b/test/xss/markdown-script-sanitization.js index ef374dd7..9d6624c7 100644 --- a/test/xss/markdown-script-sanitization.js +++ b/test/xss/markdown-script-sanitization.js @@ -5,7 +5,7 @@ import { render } from "enzyme" import Markdown from "components/providers/markdown" import { Markdown as OAS3Markdown } from "corePlugins/oas3/wrap-components/markdown.js" -describe.only("Markdown Script Sanitization", function() { +describe("Markdown Script Sanitization", function() { describe("Swagger 2.0", function() { it("sanitizes ` From 60e8091eedde05244a1d8c498b5f85f7390ed9af Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Sun, 8 Oct 2017 10:26:32 -0600 Subject: [PATCH 6/8] Add unit test for images in markdown --- src/core/components/providers/markdown.jsx | 3 ++ test/components/markdown.js | 56 +++++++++++++--------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/core/components/providers/markdown.jsx b/src/core/components/providers/markdown.jsx index ef95c6ae..2ef8b6a6 100644 --- a/src/core/components/providers/markdown.jsx +++ b/src/core/components/providers/markdown.jsx @@ -30,6 +30,9 @@ export default Markdown const sanitizeOptions = { allowedTags: sanitize.defaults.allowedTags.concat([ "h1", "h2", "img" ]), + allowedAttributes: { + "img": sanitize.defaults.allowedAttributes.img.concat(["title"]) + }, textFilter: function(text) { return text.replace(/"/g, "\"") } diff --git a/test/components/markdown.js b/test/components/markdown.js index 6dd87053..01a55e1c 100644 --- a/test/components/markdown.js +++ b/test/components/markdown.js @@ -5,34 +5,44 @@ import { render } from "enzyme" import Markdown from "components/providers/markdown" import { Markdown as OAS3Markdown } from "corePlugins/oas3/wrap-components/markdown.js" -describe.only("Markdown component", function() { - describe("Swagger 2.0", function() { - it("allows heading elements", function() { - const str = ` +describe("Markdown component", function() { + describe("Swagger 2.0", function() { + it("allows image elements", function() { + const str = `![Image alt text](http://image.source "Image title")` + const el = render() + expect(el.html()).toEqual(`

\n
`) + }) + + it("allows heading elements", function() { + const str = ` # h1 ## h2 ### h3 #### h4 ##### h5 -###### h6 - ` - const el = render() - expect(el.html()).toEqual(`

h1

\n

h2

\n

h3

\n

h4

\n
h5
\n
h6
\n
`) +###### h6` + const el = render() + expect(el.html()).toEqual(`

h1

\n

h2

\n

h3

\n

h4

\n
h5
\n
h6
\n
`) + }) }) - }) - describe("OAS 3", function() { - it("allows heading elements", function() { - const str = ` - # h1 - ## h2 - ### h3 - #### h4 - ##### h5 - ###### h6 - ` - const el = render() - expect(el.html()).toEqual(`

h1

\n

h2

\n

h3

\n

h4

\n
h5
\n
h6
`) - }) - }) + describe("OAS 3", function() { + it("allows image elements", function() { + const str = `![Image alt text](http://image.source "Image title")` + const el = render() + expect(el.html()).toEqual(`

`) + }) + + it("allows heading elements", function() { + const str = ` +# h1 +## h2 +### h3 +#### h4 +##### h5 +###### h6` + const el = render() + expect(el.html()).toEqual(`

h1

\n

h2

\n

h3

\n

h4

\n
h5
\n
h6
`) + }) + }) }) From 74165f5292258b94896d8b38536571c8892e206b Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Mon, 9 Oct 2017 12:10:41 -0700 Subject: [PATCH 7/8] Pass configuration interceptors to spec download fetch --- src/core/plugins/download-url.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/plugins/download-url.js b/src/core/plugins/download-url.js index c8dff0b8..d80e982b 100644 --- a/src/core/plugins/download-url.js +++ b/src/core/plugins/download-url.js @@ -7,13 +7,16 @@ export default function downloadUrlPlugin (toolbox) { let { fn } = toolbox const actions = { - download: (url)=> ({ errActions, specSelectors, specActions }) => { + download: (url)=> ({ errActions, specSelectors, specActions, getConfigs }) => { let { fetch } = fn + const config = getConfigs() url = url || specSelectors.url() specActions.updateLoadingStatus("loading") fetch({ url, loadSpec: true, + requestInterceptor: config.requestInterceptor || (a => a), + responseInterceptor: config.responseInterceptor || (a => a), credentials: "same-origin", headers: { "Accept": "application/json,*/*" From 2cd4989c056fd02ecf0e88c75910a1b961c2997e Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Tue, 10 Oct 2017 15:54:22 -0600 Subject: [PATCH 8/8] Fixes #3646 Fix CSS selector for markdown content inside response component. --- src/style/_layout.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/style/_layout.scss b/src/style/_layout.scss index 9b38a700..95584a7c 100644 --- a/src/style/_layout.scss +++ b/src/style/_layout.scss @@ -543,14 +543,14 @@ .response-col_description__inner { - span + div.markdown, div.renderedMarkdown { font-size: 12px; font-style: italic; display: block; - margin: 10px 0; + margin: 0; padding: 10px; border-radius: 4px;