Skip to content

Commit c9cdd07

Browse files
authored
Fix security schemes (#444)
* Create info page if title or description exists * Refactor to support all security types * Add more example security types for testing * Render scopes only if length > 0 * Fix formatting * Fix tab label and header formatting * Switch to using SchemaTabs * Use custom class to fit tabs to width
1 parent bc71cb9 commit c9cdd07

File tree

6 files changed

+293
-35
lines changed

6 files changed

+293
-35
lines changed

demo/examples/petstore.yaml

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ info:
3737
Petstore offers two forms of authentication:
3838
- API Key
3939
- OAuth2
40+
4041
OAuth2 - an open protocol to allow secure authorization in a simple
4142
and standard method from web, mobile and desktop applications.
4243
@@ -120,6 +121,13 @@ paths:
120121
- petstore_auth:
121122
- "write:pets"
122123
- "read:pets"
124+
- api_key: []
125+
- ApiKeyAuth: []
126+
- BasicAuth: []
127+
- BearerAuth: []
128+
- OAuth2: []
129+
- OpenID: []
130+
123131
x-codeSamples:
124132
- lang: "C#"
125133
source: |
@@ -1223,13 +1231,29 @@ components:
12231231
type: apiKey
12241232
name: api_key
12251233
in: header
1226-
examples:
1227-
Order:
1228-
value:
1229-
quantity: 1
1230-
shipDate: "2018-10-19T16:46:45Z"
1231-
status: placed
1232-
complete: false
1234+
BasicAuth:
1235+
type: http
1236+
scheme: basic
1237+
BearerAuth:
1238+
type: http
1239+
scheme: bearer
1240+
ApiKeyAuth:
1241+
type: apiKey
1242+
in: header
1243+
name: X-API-Key
1244+
OpenID:
1245+
type: openIdConnect
1246+
openIdConnectUrl: https://example.com/.well-known/openid-configuration
1247+
OAuth2:
1248+
type: oauth2
1249+
flows:
1250+
authorizationCode:
1251+
authorizationUrl: https://example.com/oauth/authorize
1252+
tokenUrl: https://example.com/oauth/token
1253+
scopes:
1254+
read: Grants read access
1255+
write: Grants write access
1256+
admin: Grants access to admin operations
12331257
x-webhooks:
12341258
newPet:
12351259
post:

packages/docusaurus-plugin-openapi-docs/src/markdown/createAuthentication.ts

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ export function createAuthentication(securitySchemes: SecuritySchemeObject) {
1313
if (!securitySchemes || !Object.keys(securitySchemes).length) return "";
1414

1515
const createAuthenticationTable = (securityScheme: any) => {
16-
const { bearerFormat, flows, name, scheme, type } = securityScheme;
16+
const { bearerFormat, flows, name, scheme, type, openIdConnectUrl } =
17+
securityScheme;
1718

1819
const createSecuritySchemeTypeRow = () =>
1920
create("tr", {
@@ -30,7 +31,7 @@ export function createAuthentication(securitySchemes: SecuritySchemeObject) {
3031

3132
return create("tr", {
3233
children: [
33-
create("th", { children: `${flowType} OAuth Flow:` }),
34+
create("th", { children: `OAuth Flow (${flowType}):` }),
3435
create("td", {
3536
children: [
3637
guard(tokenUrl, () =>
@@ -91,12 +92,14 @@ export function createAuthentication(securitySchemes: SecuritySchemeObject) {
9192
create("td", { children: scheme }),
9293
],
9394
}),
94-
create("tr", {
95-
children: [
96-
create("th", { children: "Bearer format:" }),
97-
create("td", { children: bearerFormat }),
98-
],
99-
}),
95+
guard(bearerFormat, () =>
96+
create("tr", {
97+
children: [
98+
create("th", { children: "Bearer format:" }),
99+
create("td", { children: bearerFormat }),
100+
],
101+
})
102+
),
100103
],
101104
}),
102105
}),
@@ -115,23 +118,51 @@ export function createAuthentication(securitySchemes: SecuritySchemeObject) {
115118
}),
116119
],
117120
});
121+
case "openIdConnect":
122+
return create("div", {
123+
children: [
124+
create("table", {
125+
children: create("tbody", {
126+
children: [
127+
createSecuritySchemeTypeRow(),
128+
guard(openIdConnectUrl, () =>
129+
create("tr", {
130+
children: [
131+
create("th", { children: "OpenID Connect URL:" }),
132+
create("td", { children: openIdConnectUrl }),
133+
],
134+
})
135+
),
136+
],
137+
}),
138+
}),
139+
],
140+
});
118141
default:
119142
return "";
120143
}
121144
};
122145

123-
const formatTabLabel = (str: string) => {
124-
const formattedLabel = str
146+
const formatTabLabel = (key: string, type: string, scheme: string) => {
147+
const formattedLabel = key
125148
.replace(/(_|-)/g, " ")
126149
.trim()
127150
.replace(/\w\S*/g, (str) => str.charAt(0).toUpperCase() + str.substr(1))
128151
.replace(/([a-z])([A-Z])/g, "$1 $2")
129152
.replace(/([A-Z])([A-Z][a-z])/g, "$1 $2");
153+
const isOAuth = type === "oauth2";
154+
const isApiKey = type === "apiKey";
155+
const isHttpBasic = type === "http" && scheme === "basic";
156+
const isHttpBearer = type === "http" && scheme === "bearer";
157+
const isOpenId = type === "openIdConnect";
130158

131-
const isOAuth = formattedLabel.toLowerCase().includes("oauth2");
132-
const isApiKey = formattedLabel.toLowerCase().includes("api");
159+
if (isOAuth) return `OAuth 2.0: ${key}`;
160+
if (isApiKey) return `API Key: ${key}`;
161+
if (isHttpBasic) return "HTTP: Basic Auth";
162+
if (isHttpBearer) return "HTTP: Bearer Auth";
163+
if (isOpenId) return `OpenID Connect: ${key}`;
133164

134-
return isOAuth ? "OAuth 2.0" : isApiKey ? "API Key" : formattedLabel;
165+
return formattedLabel;
135166
};
136167

137168
return create("div", {
@@ -141,12 +172,17 @@ export function createAuthentication(securitySchemes: SecuritySchemeObject) {
141172
id: "authentication",
142173
style: { marginBottom: "1rem" },
143174
}),
144-
create("Tabs", {
175+
create("SchemaTabs", {
176+
className: "openapi-tabs__security-schemes",
145177
children: Object.entries(securitySchemes).map(
146-
([schemeType, schemeObj]) =>
178+
([schemeKey, schemeObj]) =>
147179
create("TabItem", {
148-
label: formatTabLabel(schemeType),
149-
value: `${schemeType}`,
180+
label: formatTabLabel(
181+
schemeKey,
182+
schemeObj.type,
183+
schemeObj.scheme
184+
),
185+
value: `${schemeKey}`,
150186
children: [
151187
createDescription(schemeObj.description),
152188
createAuthenticationTable(schemeObj),

packages/docusaurus-plugin-openapi-docs/src/markdown/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export function createInfoPageMD({
8888
}: InfoPageMetadata) {
8989
return render([
9090
`import ApiLogo from "@theme/ApiLogo";\n`,
91-
`import Tabs from "@theme/Tabs";\n`,
91+
`import SchemaTabs from "@theme/SchemaTabs";\n`,
9292
`import TabItem from "@theme/TabItem";\n`,
9393
`import Export from "@theme/ApiDemoPanel/Export";\n\n`,
9494

packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ function createItems(
8888
const infoIdSpaces = openapiData.info.title.replace(" ", "-").toLowerCase();
8989
const infoId = kebabCase(infoIdSpaces);
9090

91-
if (openapiData.info.description) {
91+
if (openapiData.info.description || openapiData.info.title) {
9292
// Only create an info page if we have a description.
9393
const infoDescription = openapiData.info?.description;
9494
let splitDescription: any;

0 commit comments

Comments
 (0)