Skip to content

Commit be72c29

Browse files
segevfinershockey
authored andcommitted
feature: add withCredentials configuration key (via swagger-api#5149)
* Add the withCredentials configuration key It enables passing credentials in CORS requests. e.g. Cookies and Authorization headers. * Improve withCredentials documentation * Add unit tests for the withCredentials config * Update configuration.md * Update configuration.md * only set `withCredentials` Fetch flag if the config value is truthy there are some workarounds in the wild today that involve setting `withCredentials` on `system.fn.fetch` directly. this approach avoids mangling those existing workarounds! * add more test cases * Update configs-wrap-actions.js * Update index.js
1 parent 38def57 commit be72c29

File tree

6 files changed

+118
-4
lines changed

6 files changed

+118
-4
lines changed

docker/configurator/variables.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ const standardVariables = {
8686
VALIDATOR_URL: {
8787
type: "string",
8888
name: "validatorUrl"
89+
},
90+
WITH_CREDENTIALS: {
91+
type: "boolean",
92+
name: "withCredentials",
8993
}
9094
}
9195

@@ -102,4 +106,4 @@ const legacyVariables = {
102106
}
103107
}
104108

105-
module.exports = Object.assign({}, standardVariables, legacyVariables)
109+
module.exports = Object.assign({}, standardVariables, legacyVariables)

docs/usage/configuration.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Parameter name | Docker variable | Description
7171
<a name="showMutatedRequest"></a>`showMutatedRequest` | `SHOW_MUTATED_REQUEST` | `Boolean=true`. If set to `true`, uses the mutated request returned from a requestInterceptor to produce the curl command in the UI, otherwise the request before the requestInterceptor was applied is used.
7272
<a name="supportedSubmitMethods"></a>`supportedSubmitMethods` | `SUPPORTED_SUBMIT_METHODS` | `Array=["get", "put", "post", "delete", "options", "head", "patch", "trace"]`. List of HTTP methods that have the Try it out feature enabled. An empty array disables Try it out for all operations. This does not filter the operations from the display.
7373
<a name="validatorUrl"></a>`validatorUrl` | `VALIDATOR_URL` | `String="https://online.swagger.io/validator" OR null`. By default, Swagger-UI attempts to validate specs against swagger.io's online validator. You can use this parameter to set a different validator URL, for example for locally deployed validators ([Validator Badge](https://github.com/swagger-api/validator-badge)). Setting it to `null` will disable validation.
74+
<a name="withCredentials"></a>`withCredentials` | `WITH_CREDENTIALS` | `Boolean=false` If set to `true`, enables passing credentials, [as defined in the Fetch standard](https://fetch.spec.whatwg.org/#credentials), in CORS requests that are sent by the browser. Note that Swagger UI cannot currently set cookies cross-domain (see [swagger-js#1163](https://github.com/swagger-api/swagger-js/issues/1163)) - as a result, you will have to rely on browser-supplied cookies (which this setting enables sending) that Swagger UI cannot control.
7475

7576
##### Macros
7677

@@ -81,7 +82,7 @@ Parameter name | Docker variable | Description
8182

8283
### Instance methods
8384

84-
**💡 Take note! These are methods, not parameters**.
85+
**💡 Take note! These are methods, not parameters**.
8586

8687
Method name | Docker variable | Description
8788
--- | --- | -----
@@ -91,7 +92,7 @@ Method name | Docker variable | Description
9192

9293
### Docker
9394

94-
If you're using the Docker image, you can also control most of these options with environment variables. Each parameter has its environment variable name noted, if available.
95+
If you're using the Docker image, you can also control most of these options with environment variables. Each parameter has its environment variable name noted, if available.
9596

9697
Below are the general guidelines for using the environment variable interface.
9798

src/core/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ module.exports = function SwaggerUI(opts) {
5151
defaultModelsExpandDepth: 1,
5252
showExtensions: false,
5353
showCommonExtensions: false,
54+
withCredentials: undefined,
5455
supportedSubmitMethods: [
5556
"get",
5657
"put",
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export const loaded = (ori, system) => (...args) => {
2+
ori(...args)
3+
const value = system.getConfigs().withCredentials
4+
5+
if(value !== undefined) {
6+
system.fn.fetch.withCredentials = typeof value === "string" ? (value === "true") : !!value
7+
}
8+
}

src/core/plugins/swagger-js/index.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Swagger from "swagger-client"
2+
import * as configsWrapActions from "./configs-wrap-actions"
23

34
module.exports = function({ configs, getConfigs }) {
45
return {
@@ -22,6 +23,11 @@ module.exports = function({ configs, getConfigs }) {
2223
},
2324
serializeRes: Swagger.serializeRes,
2425
opId: Swagger.helpers.opId
25-
}
26+
},
27+
statePlugins: {
28+
configs: {
29+
wrapActions: configsWrapActions
30+
}
31+
},
2632
}
2733
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import expect, { createSpy } from "expect"
2+
import { loaded } from "corePlugins/swagger-js/configs-wrap-actions"
3+
4+
describe("swagger-js plugin - withCredentials", () => {
5+
it("should have no effect by default", () => {
6+
const system = {
7+
fn: {
8+
fetch: createSpy().andReturn(Promise.resolve())
9+
},
10+
getConfigs: () => ({})
11+
}
12+
const oriExecute = createSpy()
13+
14+
const loadedFn = loaded(oriExecute, system)
15+
loadedFn()
16+
17+
expect(oriExecute.calls.length).toBe(1)
18+
expect(system.fn.fetch.withCredentials).toBe(undefined)
19+
})
20+
21+
it("should allow setting flag to true via config", () => {
22+
const system = {
23+
fn: {
24+
fetch: createSpy().andReturn(Promise.resolve())
25+
},
26+
getConfigs: () => ({
27+
withCredentials: true
28+
})
29+
}
30+
const oriExecute = createSpy()
31+
32+
const loadedFn = loaded(oriExecute, system)
33+
loadedFn()
34+
35+
expect(oriExecute.calls.length).toBe(1)
36+
expect(system.fn.fetch.withCredentials).toBe(true)
37+
})
38+
39+
it("should allow setting flag to false via config", () => {
40+
const system = {
41+
fn: {
42+
fetch: createSpy().andReturn(Promise.resolve())
43+
},
44+
getConfigs: () => ({
45+
withCredentials: false
46+
})
47+
}
48+
const oriExecute = createSpy()
49+
50+
const loadedFn = loaded(oriExecute, system)
51+
loadedFn()
52+
53+
expect(oriExecute.calls.length).toBe(1)
54+
expect(system.fn.fetch.withCredentials).toBe(false)
55+
})
56+
57+
it("should allow setting flag to true via config as string", () => {
58+
// for query string config
59+
const system = {
60+
fn: {
61+
fetch: createSpy().andReturn(Promise.resolve())
62+
},
63+
getConfigs: () => ({
64+
withCredentials: "true"
65+
})
66+
}
67+
const oriExecute = createSpy()
68+
69+
const loadedFn = loaded(oriExecute, system)
70+
loadedFn()
71+
72+
expect(oriExecute.calls.length).toBe(1)
73+
expect(system.fn.fetch.withCredentials).toBe(true)
74+
})
75+
76+
it("should allow setting flag to false via config as string", () => {
77+
// for query string config
78+
const system = {
79+
fn: {
80+
fetch: createSpy().andReturn(Promise.resolve())
81+
},
82+
getConfigs: () => ({
83+
withCredentials: "false"
84+
})
85+
}
86+
const oriExecute = createSpy()
87+
88+
const loadedFn = loaded(oriExecute, system)
89+
loadedFn()
90+
91+
expect(oriExecute.calls.length).toBe(1)
92+
expect(system.fn.fetch.withCredentials).toBe(false)
93+
})
94+
})

0 commit comments

Comments
 (0)