Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/api.html
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,7 @@ <h2> Supported vendor extensions</h2>
<div class="table-block">
<table class="m-table">
<tr>
<td class="mono bold right" style="width:130px;" >x-code-sample <br/> x-codeSample </td>
<td class="mono bold right" style="width:140px;" >x-code-sample <br/> x-codeSample </td>
<td class="gray"> Use this vendor-extension to provide code samples in various languages
</td>
<td style="width:130px;"><a href="./examples/code-samples.html"> Usage Example </a> </td>
Expand All @@ -884,9 +884,10 @@ <h2> Supported vendor extensions</h2>
</tr>

<tr>
<td class="mono bold right">x-client-id <br/> x-client-secret </td>
<td class="mono bold right">x-client-id <br/> x-client-secret <br/> x-default-scopes </td>
<td class="gray">
Use these vendor-extensions to pre fill <span class="mono bold">client-id</span> and <span class="mono bold">client-secret</span> in the UI
Use these vendor-extensions to pre fill <span class="mono bold">client-id</span> and <span class="mono bold">client-secret</span>
and to eventually pre select <span class="mono bold">scopes</span> in the UI
</td>
<td><a href="./examples/oauth-vendor-extension.html"> Usage Example </a> </td>
</tr>
Expand Down
3 changes: 2 additions & 1 deletion docs/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,8 @@ <h2 style="font-weight:700"> OAuth Setup </h2>
<div class = "container">
<a href="./examples/oauth-vendor-extension.html"> OAuth Extensions</a>
<div class = "c-description" >
Pre fill client-id and client-secret with vendor extension 'x-client-id' and 'x-client-secret'
Pre fill client-id and client-secret with vendor extension 'x-client-id' and 'x-client-secret', and pre select
desired scopes with vendor extension 'x-default-scopes'
</div>
</div>
<div class = "container">
Expand Down
12 changes: 8 additions & 4 deletions docs/specs/oauth-vendor-extension.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ openapi: 3.0.0
info:
title: Petstore API
description: |
Example to show how to use `x-client-id` and `x-client-secret` vendor extensions to pre fill them in the UI.

Below is the Open API spec snippet that shows its usage,
and if you check the authentication section you will find that client-id and client-secret is pre-filled, the user just needs to click on `GET TOKEN`
Example to show how to use `x-client-id`, `x-client-secret` and `x-default-scopes` vendor extensions to pre fill them in the UI.

Below is the Open API spec snippet that shows its usage,
and if you check the authentication section you will find that client-id and client-secret are pre-filled, the user just needs to click on `GET TOKEN`.
Also notice that the scope `dog-lover` is already checked
```yaml
openapi: 3.0.0
...
Expand All @@ -16,6 +17,7 @@ info:
type: oauth2
x-client-id: my-client-id # <--- when provided it will be pre filled in RapiDoc UI
x-client-secret: my-client-secret # <--- when provided it will be pre filled in RapiDoc UI
x-default-scopes: [dog-lover] # <--- when provided scopes will be pre checked in RapiDoc UI
flows:
authorizationCode:
authorizationUrl: /authorize
Expand Down Expand Up @@ -53,6 +55,8 @@ components:
description: You authorize requests, by providing client credentials.
x-client-id: my-client-id
x-client-secret: my-client-secret
x-default-scopes:
- dog-lover
flows:
authorizationCode:
authorizationUrl: /authorize
Expand Down
50 changes: 25 additions & 25 deletions src/templates/security-scheme-template.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ async function onInvokeOAuthFlow(securitySchemeId, flowType, authUrl, tokenUrl,

/* eslint-disable indent */

function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, authFlow) {
function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, authFlow, defaultScopes = []) {
let { authorizationUrl, tokenUrl, refreshUrl } = authFlow.authorizationUrl;
const isUrlAbsolute = (url) => (url.indexOf('://') > 0 || url.indexOf('//') === 0);
if (refreshUrl && !isUrlAbsolute(refreshUrl)) {
Expand All @@ -277,8 +277,8 @@ function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, a
flowNameDisplay = flowName;
}
return html`
<div class="oauth-flow ${flowName}" style="padding: 12px 0; margin-bottom:12px;">
<div class="tiny-title upper" style="margin-bottom:8px;">${flowNameDisplay}</div>
<div class="oauth-flow ${flowName}" style="padding: 12px 0; margin-bottom:12px;">
<div class="tiny-title upper" style="margin-bottom:8px;">${flowNameDisplay}</div>
${authorizationUrl
? html`<div style="margin-bottom:5px"><span style="width:75px; display: inline-block;">Auth URL</span> <span class="mono-font"> ${authorizationUrl} </span></div>`
: ''
Expand All @@ -299,7 +299,7 @@ function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, a
<div class= "oauth-scopes" part="section-auth-scopes" style = "width:100%; display:flex; flex-direction:column; flex-wrap:wrap; margin:0 0 10px 24px">
${Object.entries(authFlow.scopes).map((scopeAndDescr, index) => html`
<div class="m-checkbox" style="display:inline-flex; align-items:center">
<input type="checkbox" part="checkbox checkbox-auth-scope" class="scope-checkbox" id="${securitySchemeId}${flowName}${index}" value="${scopeAndDescr[0]}">
<input type="checkbox" part="checkbox checkbox-auth-scope" class="scope-checkbox" id="${securitySchemeId}${flowName}${index}" ?checked="${defaultScopes.includes(scopeAndDescr[0])}" value="${scopeAndDescr[0]}">
<label for="${securitySchemeId}${flowName}${index}" style="margin-left:5px; cursor:pointer">
<span class="mono-font">${scopeAndDescr[0]}</span>
${scopeAndDescr[0] !== scopeAndDescr[1] ? ` - ${scopeAndDescr[1] || ''}` : ''}
Expand All @@ -317,16 +317,16 @@ function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, a
<input type="password" value = "" placeholder="password" spellcheck="false" class="oauth2 ${flowName} ${securitySchemeId} api-key-password" style = "margin:0 5px;" part="textbox textbox-password">
</div>`
: ''
}
}
<div>
${flowName === 'authorizationCode'
? html`
<div style="margin: 16px 0 4px">
<input type="checkbox" part="checkbox checkbox-auth-scope" id="${securitySchemeId}-pkce" checked>
<input type="checkbox" part="checkbox checkbox-auth-scope" id="${securitySchemeId}-pkce" checked>
<label for="${securitySchemeId}-pkce" style="margin:0 16px 0 4px; line-height:24px; cursor:pointer">
Send Proof Key for Code Exchange (PKCE)
</label>
</div>
</div>
`
: ''
}
Expand All @@ -337,8 +337,8 @@ function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, a
${flowName === 'authorizationCode' || flowName === 'clientCredentials' || flowName === 'password'
? html`
<select style="margin-right:5px;" class="${flowName} ${securitySchemeId} oauth-send-client-secret-in">
<option value = 'header' selected> Authorization Header </option>
<option value = 'request-body'> Request Body </option>
<option value = 'header' selected> Authorization Header </option>
<option value = 'request-body'> Request Body </option>
</select>`
: ''
}`
Expand All @@ -356,7 +356,7 @@ function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, a
`
: ''
}
</div>
</div>
`;
}

Expand Down Expand Up @@ -424,14 +424,14 @@ export default function securitySchemeTemplate() {
? html`Send <code>${v.name}</code> in <code>${v.in}</code>`
: html`Send <code>Authorization</code> in <code>header</code> containing the word <code>Bearer</code> followed by a space and a Token String.`
}
</div>
</div>
<div style="max-height:28px;">
${v.in !== 'cookie'
? html`
<input type = "text" value = "${v.value}" class="${v.type} ${v.securitySchemeId} api-key-input" placeholder = "api-token" spellcheck = "false">
<button class="m-btn thin-border" style = "margin-left:5px;"
part = "btn btn-outline"
@click="${(e) => { onApiKeyChange.call(this, v.securitySchemeId, e); }}">
@click="${(e) => { onApiKeyChange.call(this, v.securitySchemeId, e); }}">
${v.finalKeyValue ? 'UPDATE' : 'SET'}
</button>`
: html`<span class="gray-text" style="font-size::var(--font-size-small)"> cookies cannot be set from here</span>`
Expand All @@ -443,14 +443,14 @@ export default function securitySchemeTemplate() {
? html`
<div style="margin-bottom:5px">
Send <code>Authorization</code> in <code>header</code> containing the word <code>Basic</code> followed by a space and a base64 encoded string of <code>username:password</code>.
</div>
</div>
<div>
<input type="text" value = "${v.user}" placeholder="username" spellcheck="false" class="${v.type} ${v.securitySchemeId} api-key-user" style="width:100px">
<input type="password" value = "${v.password}" placeholder="password" spellcheck="false" class="${v.type} ${v.securitySchemeId} api-key-password" style = "width:100px; margin:0 5px;">
<button class="m-btn thin-border"
@click="${(e) => { onApiKeyChange.call(this, v.securitySchemeId, e); }}"
part = "btn btn-outline"
>
>
${v.finalKeyValue ? 'UPDATE' : 'SET'}
</button>
</div>`
Expand All @@ -462,12 +462,12 @@ export default function securitySchemeTemplate() {
? html`
<tr>
<td style="border:none; padding-left:48px">
${Object.keys(v.flows).map((f) => oAuthFlowTemplate.call(this, f, v['x-client-id'], v['x-client-secret'], v.securitySchemeId, v.flows[f]))}
${Object.keys(v.flows).map((f) => oAuthFlowTemplate.call(this, f, v['x-client-id'], v['x-client-secret'], v.securitySchemeId, v.flows[f], v['x-default-scopes']))}
</td>
</tr>
</tr>
`
: ''
}
}
`)}
</table>`
: ''
Expand Down Expand Up @@ -507,7 +507,7 @@ export function pathSecurityTemplate(pathSecurity) {
</g>
</svg>
${orSecurityKeys1.map((orSecurityItem1, i) => html`

${orSecurityItem1.securityTypes
? html`
${i !== 0 ? html`<div style="padding:3px 4px;"> OR </div>` : ''}
Expand All @@ -522,11 +522,11 @@ export function pathSecurityTemplate(pathSecurity) {
const scopeHtml = html`${andSecurityItem.scopes !== ''
? html`
<div>
<b>Required scopes:</b>
<br/>
<div style="margin-left:8px">
<b>Required scopes:</b>
<br/>
<div style="margin-left:8px">
${andSecurityItem.scopes.split(',').map((scope, cnt) => html`${cnt === 0 ? '' : '┃'}<span>${scope}</span>`)}
</div>
</div>
</div>`
: ''
}`;
Expand All @@ -545,19 +545,19 @@ export function pathSecurityTemplate(pathSecurity) {
: andSecurityItem.type === 'http'
? html`
<div>
${orSecurityItem1.securityDefs.length > 1 ? html`<b>${j + 1}.</b> &nbsp;` : html`Requires`}
${orSecurityItem1.securityDefs.length > 1 ? html`<b>${j + 1}.</b> &nbsp;` : html`Requires`}
${andSecurityItem.scheme === 'basic' ? 'Base 64 encoded username:password' : 'Bearer Token'} in <b>Authorization header</b>
${scopeHtml}
</div>`
: html`
<div>
${orSecurityItem1.securityDefs.length > 1 ? html`<b>${j + 1}.</b> &nbsp;` : html`Requires`}
${orSecurityItem1.securityDefs.length > 1 ? html`<b>${j + 1}.</b> &nbsp;` : html`Requires`}
Token in <b>${andSecurityItem.name} ${andSecurityItem.in}</b>
${scopeHtml}
</div>`
}`;
})}
</div>
</div>
</div>
</div>
`
Expand Down