diff --git a/Dockerfile b/Dockerfile
index d5098ae8f8a..27e167a9fdd 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -24,14 +24,16 @@ ENV API_KEY="**None**" \
CORS="true" \
EMBEDDING="false"
-COPY --chown=nginx:nginx --chmod=0666 ./docker/default.conf.template ./docker/cors.conf ./docker/embedding.conf /etc/nginx/templates/
+COPY --chmod=0644 ./docker/default.conf.template ./docker/cors.conf ./docker/embedding.conf /etc/nginx/templates/
-COPY --chmod=0666 ./dist/* /usr/share/nginx/html/
-COPY --chmod=0555 ./docker/docker-entrypoint.d/ /docker-entrypoint.d/
-COPY --chmod=0666 ./docker/configurator /usr/share/nginx/configurator
+COPY --chmod=0644 ./dist/* /usr/share/nginx/html/
+COPY --chmod=0755 ./docker/docker-entrypoint.d/ /docker-entrypoint.d/
+COPY --chmod=0644 ./docker/configurator /usr/share/nginx/configurator
# Simulates running NGINX as a non root; in future we want to use nginxinc/nginx-unprivileged.
# In future we will have separate unpriviledged images tagged as v5.1.2-unprivileged.
-RUN chmod 777 /usr/share/nginx/html/ /etc/nginx/conf.d/ /etc/nginx/conf.d/default.conf /var/cache/nginx/ /var/run/
+RUN chmod 777 /etc/nginx/conf.d/ /usr/share/nginx/html/ /var/cache/nginx/ /var/run/ && \
+ chmod 666 /etc/nginx/conf.d/default.conf /usr/share/nginx/html/swagger-initializer.js && \
+ chmod 755 /etc/nginx/templates /usr/share/nginx/configurator
EXPOSE 8080
diff --git a/package-lock.json b/package-lock.json
index 221d372e217..c4721f9a251 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "swagger-ui",
- "version": "5.26.2",
+ "version": "5.27.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "swagger-ui",
- "version": "5.26.2",
+ "version": "5.27.0",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime-corejs3": "^7.27.1",
diff --git a/package.json b/package.json
index febc48d5928..34a02d36c65 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "swagger-ui",
- "version": "5.26.2",
+ "version": "5.27.0",
"main": "./dist/swagger-ui.js",
"module": "./dist/swagger-ui-es-bundle-core.js",
"exports": {
diff --git a/src/core/plugins/json-schema-2020-12-samples/fn/main.js b/src/core/plugins/json-schema-2020-12-samples/fn/main.js
index a0ef02c87a0..c5c3d704baf 100644
--- a/src/core/plugins/json-schema-2020-12-samples/fn/main.js
+++ b/src/core/plugins/json-schema-2020-12-samples/fn/main.js
@@ -482,6 +482,8 @@ export const sampleFromSchemaGeneric = (
) {
res[displayName].push(additionalPropSample)
} else {
+ const keyName =
+ additionalProps?.["x-additionalPropertiesName"] || "additionalProp"
const toGenerateCount =
Number.isInteger(schema.minProperties) &&
schema.minProperties > 0 &&
@@ -494,10 +496,10 @@ export const sampleFromSchemaGeneric = (
}
if (respectXML) {
const temp = {}
- temp["additionalProp" + i] = additionalPropSample["notagname"]
+ temp[keyName + i] = additionalPropSample["notagname"]
res[displayName].push(temp)
} else {
- res["additionalProp" + i] = additionalPropSample
+ res[keyName + i] = additionalPropSample
}
propertyAddedCounter++
}
diff --git a/src/core/plugins/json-schema-5-samples/fn/index.js b/src/core/plugins/json-schema-5-samples/fn/index.js
index 2741a19b918..44e677c0c4a 100644
--- a/src/core/plugins/json-schema-5-samples/fn/index.js
+++ b/src/core/plugins/json-schema-5-samples/fn/index.js
@@ -518,6 +518,7 @@ export const sampleFromSchemaGeneric = (schema, config={}, exampleOverride = und
{
res[displayName].push(additionalPropSample)
} else {
+ const keyName = additionalProps["x-additionalPropertiesName"] || "additionalProp"
const toGenerateCount = schema.minProperties !== null && schema.minProperties !== undefined && propertyAddedCounter < schema.minProperties
? schema.minProperties - propertyAddedCounter
: 3
@@ -527,10 +528,10 @@ export const sampleFromSchemaGeneric = (schema, config={}, exampleOverride = und
}
if(respectXML) {
const temp = {}
- temp["additionalProp" + i] = additionalPropSample["notagname"]
+ temp[keyName + i] = additionalPropSample["notagname"]
res[displayName].push(temp)
} else {
- res["additionalProp" + i] = additionalPropSample
+ res[keyName + i] = additionalPropSample
}
propertyAddedCounter++
}
diff --git a/src/core/utils/url.js b/src/core/utils/url.js
index 24cce9a4de1..4186b72909a 100644
--- a/src/core/utils/url.js
+++ b/src/core/utils/url.js
@@ -58,11 +58,19 @@ export function sanitizeUrl(url) {
// return sanitized URI reference
if (urlObject.origin === base) {
- return urlTrimmed.startsWith("/")
- ? `${urlObject.pathname}${urlObject.search}${urlObject.hash}`
- : urlTrimmed.startsWith(".")
- ? `.${urlObject.pathname}${urlObject.search}${urlObject.hash}`
- : `${urlObject.pathname.substring(1)}${urlObject.search}${urlObject.hash}`
+ if (urlTrimmed.startsWith("/")) {
+ return `${urlObject.pathname}${urlObject.search}${urlObject.hash}`
+ }
+
+ if (urlTrimmed.startsWith("./")) {
+ return `.${urlObject.pathname}${urlObject.search}${urlObject.hash}`
+ }
+
+ if (urlTrimmed.startsWith("../")) {
+ return `..${urlObject.pathname}${urlObject.search}${urlObject.hash}`
+ }
+
+ return `${urlObject.pathname.substring(1)}${urlObject.search}${urlObject.hash}`
}
return String(urlObject)
diff --git a/test/unit/core/plugins/json-schema-2020-12-samples/fn.js b/test/unit/core/plugins/json-schema-2020-12-samples/fn.js
index 8eb34470742..743c3a2b9dc 100644
--- a/test/unit/core/plugins/json-schema-2020-12-samples/fn.js
+++ b/test/unit/core/plugins/json-schema-2020-12-samples/fn.js
@@ -1263,6 +1263,30 @@ describe("sampleFromSchema", () => {
expect(sampleFromSchema(definition)).toEqual(expected)
})
+ it("should handle additionalProperties with x-additionalPropertiesName", () => {
+ const definition = {
+ type: "object",
+ additionalProperties: {
+ type: "string",
+ "x-additionalPropertiesName": "bar",
+ },
+ properties: {
+ foo: {
+ type: "string",
+ },
+ },
+ }
+
+ const expected = {
+ foo: "string",
+ bar1: "string",
+ bar2: "string",
+ bar3: "string",
+ }
+
+ expect(sampleFromSchema(definition)).toEqual(expected)
+ })
+
it("should handle additionalProperties=true", () => {
const definition = {
type: "object",
@@ -2765,6 +2789,28 @@ describe("createXMLExample", function () {
expect(sut(definition)).toEqual(expected)
})
+ it("returns object with additional props with x-additionalPropertiesName", function () {
+ const expected =
+ '\n\n\tstring\n\tstring\n\tstring\n\tstring\n'
+ const definition = {
+ type: "object",
+ properties: {
+ dog: {
+ type: "string",
+ },
+ },
+ additionalProperties: {
+ type: "string",
+ "x-additionalPropertiesName": "animal",
+ },
+ xml: {
+ name: "animals",
+ },
+ }
+
+ expect(sut(definition)).toEqual(expected)
+ })
+
it("returns object with additional props =true", function () {
const expected =
'\n\n\tstring\n\tAnything can be here\n'
diff --git a/test/unit/core/plugins/json-schema-5-samples/fn/index.js b/test/unit/core/plugins/json-schema-5-samples/fn/index.js
index 34f9c9df4d6..8e0ab369d3a 100644
--- a/test/unit/core/plugins/json-schema-5-samples/fn/index.js
+++ b/test/unit/core/plugins/json-schema-5-samples/fn/index.js
@@ -969,6 +969,30 @@ describe("sampleFromSchema", () => {
expect(sampleFromSchema(definition)).toEqual(expected)
})
+ it("should handle additionalProperties with x-additionalPropertiesName", () => {
+ const definition = {
+ type: "object",
+ additionalProperties: {
+ type: "string",
+ "x-additionalPropertiesName": "bar",
+ },
+ properties: {
+ foo: {
+ type: "string",
+ },
+ },
+ }
+
+ const expected = {
+ foo: "string",
+ bar1: "string",
+ bar2: "string",
+ bar3: "string",
+ }
+
+ expect(sampleFromSchema(definition)).toEqual(expected)
+ })
+
it("should handle additionalProperties=true", () => {
const definition = {
type: "object",
@@ -2223,6 +2247,27 @@ describe("createXMLExample", function () {
expect(sut(definition)).toEqual(expected)
})
+ it("returns object with additional props with x-additionalPropertiesName", function () {
+ let expected = "\n\n\tstring\n\tstring\n\tstring\n\tstring\n"
+ let definition = {
+ type: "object",
+ properties: {
+ dog: {
+ type: "string"
+ }
+ },
+ additionalProperties: {
+ type: "string",
+ "x-additionalPropertiesName": "animal"
+ },
+ xml: {
+ name: "animals"
+ }
+ }
+
+ expect(sut(definition)).toEqual(expected)
+ })
+
it("returns object with additional props =true", function () {
let expected = "\n\n\tstring\n\tAnything can be here\n"
let definition = {
diff --git a/test/unit/core/utils.js b/test/unit/core/utils.js
index 80e7654dce8..068954d5fa2 100644
--- a/test/unit/core/utils.js
+++ b/test/unit/core/utils.js
@@ -1449,6 +1449,13 @@ describe("utils", () => {
expect(sanitizeUrl(url)).toEqual("https://swagger.io/")
})
+ it("should gracefully handle relative paths", () => {
+ expect(sanitizeUrl(".openapi.json")).toEqual(".openapi.json")
+ expect(sanitizeUrl("./openapi.json")).toEqual("./openapi.json")
+ expect(sanitizeUrl("..openapi.json")).toEqual("..openapi.json")
+ expect(sanitizeUrl("../openapi.json")).toEqual("../openapi.json")
+ })
+
it("should gracefully handle empty strings", () => {
expect(sanitizeUrl("")).toEqual("")
})