UNPKG

openapi-explorer

Version:

OpenAPI Explorer - API viewer with dynamically generated components, documentation, and interaction console

349 lines (341 loc) 25.1 kB
"use strict"; exports.__esModule = true; exports.checkForAuthToken = checkForAuthToken; exports.default = securitySchemeTemplate; exports.pathSecurityTemplate = pathSecurityTemplate; var _lit = require("lit"); var _unsafeHtml = require("lit/directives/unsafe-html.js"); var _commonUtils = require("../utils/common-utils.js"); var _base64url = _interopRequireDefault(require("base64url")); var _index = require("../languages/index.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function onUserEnteredNewApiKeyValue(apiKeyId, e) { e.preventDefault(); let apiKeyValue = ''; const securityObj = this.resolvedSpec.securitySchemes.find(v => v.apiKeyId === apiKeyId); if (!securityObj) { return; } const trEl = e.target.closest('tr'); if (securityObj.type && securityObj.type === 'http' && securityObj.scheme && securityObj.scheme.toLowerCase() === 'basic') { const userVal = trEl.querySelector('.api-key-user').value.trim(); const passwordVal = trEl.querySelector('.api-key-password').value.trim(); if (passwordVal) { apiKeyValue = `Basic ${btoa(`${userVal}:${passwordVal}`)}`; } } else { apiKeyValue = trEl.querySelector('.api-key-input').value.trim(); if (apiKeyValue) { if (securityObj.scheme && securityObj.scheme.toLowerCase() === 'bearer') { apiKeyValue = `Bearer ${apiKeyValue.replace(/^Bearer\s+/i, '')}`; } } } securityObj.finalKeyValue = apiKeyValue; this.requestUpdate(); } function onClearAllApiKeys() { this.resolvedSpec.securitySchemes.forEach(v => { v.user = ''; v.password = ''; v.value = ''; v.finalKeyValue = ''; }); this.requestUpdate(); } // Updates the OAuth Access Token (API key), so it reflects in UI and gets used in TRY calls function updateOAuthKey(apiKeyId, tokenType = 'Bearer', accessToken) { const securityObj = this.resolvedSpec.securitySchemes.find(v => v.apiKeyId === apiKeyId); const tokenPrefix = tokenType && tokenType.toLowerCase() === 'bearer' ? 'Bearer' : tokenType; securityObj.finalKeyValue = `${tokenPrefix}${tokenPrefix ? ' ' : ''}${accessToken}`; this.requestUpdate(); } // Gets Access-Token in exchange of Authorization Code async function fetchAccessToken(tokenUrl, suggestedClientId, clientSecret, redirectUrl, grantType, authCode, sendClientSecretIn = 'header', apiKeyId, authFlowDivEl, scopes = null) { const respDisplayEl = authFlowDivEl ? authFlowDivEl.querySelector('.oauth-resp-display') : undefined; const { codeVerifier, clientId: requestClientId } = JSON.parse(localStorage.getItem('openapi-explorer-oauth') || '{}'); localStorage.removeItem('openapi-explorer-oauth'); const clientId = suggestedClientId || requestClientId; const urlFormParams = new URLSearchParams(); const headers = new Headers(); urlFormParams.append('grant_type', grantType); if (redirectUrl) { urlFormParams.append('redirect_uri', redirectUrl); } if (authCode) { urlFormParams.append('code', authCode); } if (sendClientSecretIn === 'header') { headers.set('Authorization', `Basic ${btoa(`${clientId}:${clientSecret}`)}`); } else { urlFormParams.append('client_id', clientId); if (clientSecret) { urlFormParams.append('client_secret', clientSecret); } } if (scopes) { urlFormParams.append('scope', scopes); } if (codeVerifier) { urlFormParams.append('code_verifier', codeVerifier); } try { const resp = await fetch(tokenUrl, { method: 'POST', headers, body: urlFormParams }); const tokenResp = await resp.json(); if (!resp.ok) { if (respDisplayEl) { respDisplayEl.innerHTML = `<span style="color:var(--red)">${tokenResp.error_description || tokenResp.error_description || 'Unable to get access token'}</span>`; } return; } if (tokenResp.token_type && tokenResp.access_token) { updateOAuthKey.call(this, apiKeyId, tokenResp.token_type, tokenResp.access_token); if (respDisplayEl) { respDisplayEl.innerHTML = '<span style="color:var(--green)">Access Token Received</span>'; } } } catch (err) { if (respDisplayEl) { respDisplayEl.innerHTML = '<span style="color:var(--red)">Failed to get access token</span>'; } } } function getCookieValue(keyId) { const foundCookie = (document.cookie || '').split(';').find(c => c.split('=')[0] === keyId); return foundCookie && foundCookie.split('=')[1] || ''; } function toObject(urlSearchParams) { const result = {}; const entries = urlSearchParams && urlSearchParams.entries() || []; for (const [key, value] of entries) { result[key] = value; } return result; } // Gets invoked when it receives the Authorization Code from the other window via message-event async function checkForAuthToken(redirectToApiLocation) { const parameters = toObject(new URLSearchParams(window.location.search)); const hashQuery = toObject(new URLSearchParams(window.location.hash.slice(1))); Object.assign(parameters, hashQuery); const newUrl = new URL(window.location); newUrl.searchParams.delete('nonce'); newUrl.searchParams.delete('expires_in'); newUrl.searchParams.delete('access_token'); newUrl.searchParams.delete('token_type'); newUrl.searchParams.delete('id_token'); newUrl.searchParams.delete('state'); newUrl.searchParams.delete('code'); newUrl.searchParams.delete('iss'); newUrl.searchParams.delete('scope'); newUrl.searchParams.delete('prompt'); newUrl.searchParams.delete('hd'); newUrl.searchParams.delete('authuser'); newUrl.searchParams.delete('redirect_auth'); if (!parameters.state) { return; } const sanitizedUrlWithHash = newUrl.toString().replace(/#((code|state|access_token|id_token|authuser|expires_in|hd|prompt|scope|token_type)=[^&]+&?)*$/ig, ''); history.replaceState({}, undefined, sanitizedUrlWithHash); let parsedState; try { // If somehow the state contains a question mark, just remove it, a ? is not a valid here parsedState = JSON.parse(_base64url.default.decode(parameters.state.replace(/\?.*$/, ''))); } catch (error) { // eslint-disable-next-line no-console console.error('The state parameter in the OAuth response is invalid', error, parameters.state); return; } const { apiKeyId, flowId, url } = parsedState; if (redirectToApiLocation && url && !parameters.redirect_auth) { const apiExplorerLocation = new URL(url); Object.keys(parameters).forEach(key => apiExplorerLocation.searchParams.append(key, parameters[key])); apiExplorerLocation.searchParams.append('redirect_auth', true); window.location.replace(apiExplorerLocation.toString()); return; } if (parameters.code) { var _this$selectedServer; const securityObj = this.resolvedSpec.securitySchemes.find(v => v.apiKeyId === apiKeyId); const tokenUrl = securityObj && securityObj.flows[flowId] && new URL(securityObj.flows[flowId].tokenUrl || '', (_this$selectedServer = this.selectedServer) === null || _this$selectedServer === void 0 ? void 0 : _this$selectedServer.computedUrl); await fetchAccessToken.call(this, tokenUrl, securityObj.clientId, securityObj.clientSecret, securityObj.redirectUri || window.location.href, 'authorization_code', parameters.code, null, apiKeyId); return; } updateOAuthKey.call(this, apiKeyId, parameters.token_type, parameters.access_token); } async function onInvokeOAuthFlow(apiKeyId, flowType, authUrl, tokenUrl, e) { const authFlowDivEl = e.target.closest('.oauth-flow'); const clientId = authFlowDivEl.querySelector('#oauth-client-id') ? authFlowDivEl.querySelector('#oauth-client-id').value.trim() : ''; const clientSecret = authFlowDivEl.querySelector('#oauth-client-secret') ? authFlowDivEl.querySelector('#oauth-client-secret').value.trim() : ''; const sendClientSecretIn = authFlowDivEl.querySelector('#oauth-send-client-secret-in') ? authFlowDivEl.querySelector('#oauth-send-client-secret-in').value.trim() : 'header'; const checkedScopeEls = [...authFlowDivEl.querySelectorAll('input[type="checkbox"]:checked')]; const securityObj = this.resolvedSpec.securitySchemes.find(v => v.apiKeyId === apiKeyId); let grantType = ''; let responseType = ''; // clear previous error messages const errEls = [...authFlowDivEl.parentNode.querySelectorAll('.oauth-resp-display')]; errEls.forEach(v => { v.innerHTML = ''; }); if (flowType === 'authorizationCode' || flowType === 'implicit') { const authUrlObj = new URL(authUrl); const authCodeParams = new URLSearchParams(authUrlObj.search); let codeVerifier; if (flowType === 'authorizationCode') { const randomBytes = new Uint32Array(12); (window.crypto || window.msCrypto).getRandomValues(randomBytes); authCodeParams.set('nonce', randomBytes.toString('hex').split(',').join('')); grantType = 'authorization_code'; responseType = 'code'; codeVerifier = randomBytes.toString('hex').split(',').join(''); const hash = await (window.crypto || window.msCrypto).subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier)); const codeChallenge = (0, _base64url.default)(hash); authCodeParams.set('code_challenge', codeChallenge); authCodeParams.set('code_challenge_method', 'S256'); } else if (flowType === 'implicit') { responseType = 'token'; } localStorage.setItem('openapi-explorer-oauth', JSON.stringify({ codeVerifier, clientId, apiKeyId, flowId: flowType })); const selectedScopes = checkedScopeEls.map(v => v.value).join(' '); if (selectedScopes) { authCodeParams.set('scope', selectedScopes); } authCodeParams.set('client_id', clientId); authCodeParams.set('redirect_uri', securityObj.redirectUri || window.location.href); authCodeParams.set('response_type', responseType); authCodeParams.set('state', _base64url.default.encode(JSON.stringify({ apiKeyId, flowId: flowType, url: window.location.href }))); authUrlObj.search = authCodeParams.toString(); window.location.assign(authUrlObj.toString()); } else if (flowType === 'clientCredentials') { grantType = 'client_credentials'; const selectedScopes = checkedScopeEls.map(v => v.value).join(' '); fetchAccessToken.call(this, tokenUrl, clientId, clientSecret, '', grantType, '', sendClientSecretIn, apiKeyId, authFlowDivEl, selectedScopes); } } /* eslint-disable indent */ function oAuthFlowTemplate(flowName, securityObj, authFlow) { var _this$selectedServer3, _this$selectedServer4, _this$selectedServer5; const apiKeyId = securityObj.apiKeyId; const getFullUrl = url => { var _this$selectedServer2; return url ? new URL(url, (_this$selectedServer2 = this.selectedServer) === null || _this$selectedServer2 === void 0 ? void 0 : _this$selectedServer2.computedUrl) : undefined; }; const authorizationUrl = getFullUrl(authFlow.authorizationUrl, (_this$selectedServer3 = this.selectedServer) === null || _this$selectedServer3 === void 0 ? void 0 : _this$selectedServer3.computedUrl); const tokenUrl = getFullUrl(authFlow.tokenUrl, (_this$selectedServer4 = this.selectedServer) === null || _this$selectedServer4 === void 0 ? void 0 : _this$selectedServer4.computedUrl); const refreshUrl = getFullUrl(authFlow.refreshUrl, (_this$selectedServer5 = this.selectedServer) === null || _this$selectedServer5 === void 0 ? void 0 : _this$selectedServer5.computedUrl); let flowNameDisplay; if (flowName === 'authorizationCode') { flowNameDisplay = 'Authorization Code Flow'; } else if (flowName === 'clientCredentials') { flowNameDisplay = 'Client Credentials Flow'; } else if (flowName === 'implicit') { flowNameDisplay = 'Implicit Flow'; } else { flowNameDisplay = flowName; } return (0, _lit.html)` <div class="oauth-flow" style="padding:10px 0;margin-bottom:10px"> <div class="tiny-title upper" style="margin-bottom:5px">${flowNameDisplay}</div> ${authorizationUrl ? (0, _lit.html)`<div><span style="width:75px;display:inline-block">Auth URL</span> <span class="mono-font"> ${authorizationUrl} </span></div>` : ''} ${tokenUrl ? (0, _lit.html)`<div><span style="width:75px;display:inline-block">Token URL</span> <span class="mono-font">${tokenUrl}</span></div>` : ''} ${refreshUrl ? (0, _lit.html)`<div><span style="width:75px;display:inline-block">Refresh URL</span> <span class="mono-font">${refreshUrl}</span></div>` : ''} ${flowName === 'authorizationCode' || flowName === 'clientCredentials' || flowName === 'implicit' ? (0, _lit.html)` ${authFlow.scopes ? (0, _lit.html)` <span> Scopes </span> <div class="oauth-scopes" part="section-auth-scopes" style="width:100%;display:flex;flex-direction:column;flex-wrap:wrap;margin:0 0 .125rem 0"> ${Object.entries(authFlow.scopes).map((scopeAndDescr, index) => (0, _lit.html)` <div class="m-checkbox" style="display:inline-flex;align-items:center"> <input type="checkbox" checked="checked" part="checkbox checkbox-auth-scope" id="${flowName}${index}" value="${scopeAndDescr[0]}"> <label for="${flowName}${index}" style="margin-left:5px"> <span class="mono-font">${scopeAndDescr[0]}</span> ${scopeAndDescr[0] !== scopeAndDescr[1] ? ` - ${scopeAndDescr[1] || ''}` : ''} </label> </div> `)} </div> ` : ''} <div style="display:flex"> <div> <input id="oauth-client-id" type="text" part="textbox textbox-auth-client-id" value="${securityObj.clientId || ''}" placeholder="Client ID" spellcheck="false" class="oauth-client-input"> ${flowName === 'clientCredentials' ? (0, _lit.html)` <input id="oauth-client-secret" type="password" part="textbox textbox-auth-client-secret" value="" placeholder="Client Secret" spellcheck="false" class="oauth-client-input"> <select id="oauth-send-client-secret-in" aria-label="oauth client secret location" style="margin-right:5px" class="oauth-client-input"> <option value="header" selected="selected">${(0, _index.getI18nText)('authentication.auth-header')}</option> <option value="request-body">${(0, _index.getI18nText)('operations.request-body')}</option> </select> ` : (0, _lit.html)`<div style="width:5px"></div>`} </div> ${flowName === 'authorizationCode' || flowName === 'clientCredentials' || flowName === 'implicit' ? (0, _lit.html)` <div class="oauth-client-input" style="margin-left:1rem"> <button class="m-btn thin-border" part="btn btn-outline" @click="${e => { onInvokeOAuthFlow.call(this, apiKeyId, flowName, authorizationUrl, tokenUrl, e); }}">${(0, _index.getI18nText)('authentication.get')}</button> </div>` : ''} </div> <div class="oauth-resp-display red-text small-font-size"></div> ` : ''} </div> `; } function renderSecurityScheme(v) { if (!v.type) { return ''; } if (v.type.toLowerCase() === 'apikey' || v.type.toLowerCase() === 'http' && v.scheme && v.scheme.toLowerCase() === 'bearer') { var _v$bearerFormat, _v$bearerFormat2; return (0, _lit.html)` <style>code{font-weight:700}</style> <div style="padding-top:1rem"> ${v.type.toLowerCase() === 'apikey' ? (0, _lit.html)`Sends <code>${v.name || 'API key'}</code> in <code>${v.in || 'the request'}</code> with the given value:` : (0, _lit.html)`Sends the <code>Authorization header</code> containing the token type <code style="text-transform:capitalize">${v.scheme || 'bearer'}</code> followed by the <code>${(_v$bearerFormat = v.bearerFormat) !== null && _v$bearerFormat !== void 0 ? _v$bearerFormat : 'Token'}</code> string.`} </div> <form style="height:50px;margin-top:1rem;padding:10px 0;margin-bottom:10px"> ${v.in === 'cookie' ? (0, _lit.html)` <div style="display:block"> <input type="text" value="${getCookieValue(v.apiKeyId)}" disabled="disabled" class="api-key-input" placeholder="IygRVGf54B59e0GAkKmigGfuiVlp/uhFfk2ifA+jMMJzau2F1jPldc09gPTfnMw13BFBxqUZIFDm55DPfwkb0A==" spellcheck="false" style="resize:horizontal;width:100%"> <br> <small> <strong>Cookies</strong>&nbsp;are set and configured by the remote service, therefore it is not possible to configure them from the browser. </small> </div>` : !v.finalKeyValue ? (0, _lit.html)` <input autocomplete="on" name="api-key" type="text" value="${v.value}" placeholder="${(_v$bearerFormat2 = v.bearerFormat) !== null && _v$bearerFormat2 !== void 0 ? _v$bearerFormat2 : 'api-token'}" spellcheck="false" class="api-key-input fs-exclude ph-no-capture" data-hj-suppress data-sl="mask"> <button type="submit" class="m-btn thin-border" style="margin-left:5px" part="btn btn-outline" @click="${e => { onUserEnteredNewApiKeyValue.call(this, v.apiKeyId, e); }}"> ${(0, _index.getI18nText)('authentication.set')} </button>` : (0, _lit.html)`<span class="blue-text" style="margin-right:1rem">Key Applied</span> <button class="m-btn thin-border small" part="btn btn-outline" @click="${() => { v.finalKeyValue = ''; this.requestUpdate(); }}">${(0, _index.getI18nText)('authentication.remove')}</button>`} </form>`; } if (v.type.toLowerCase() === 'http' && v.scheme && v.scheme.toLowerCase() === 'basic') { if (v.finalKeyValue) { return (0, _lit.html)` <style>code{font-weight:700}</style> <div style="padding-top:1rem">${(0, _unsafeHtml.unsafeHTML)((0, _index.getI18nText)('authentication.http-basic-desc'))}</div> <div style="height:50px;margin-top:1rem;padding:10px 0;margin-bottom:10px"> <span class="blue-text" style="margin-right:1rem">Key Applied</span> <button class="m-btn thin-border small" part="btn btn-outline" @click="${() => { v.finalKeyValue = ''; this.requestUpdate(); }}">${(0, _index.getI18nText)('authentication.remove')}</button> </div>`; } return (0, _lit.html)` <style>code{font-weight:700}</style> <div style="padding-top:1rem">${(0, _unsafeHtml.unsafeHTML)((0, _index.getI18nText)('authentication.http-basic-desc'))}</div> <div style="height:50px;margin-top:1rem;padding:10px 0;margin-bottom:10px"> <form style="display:flex"> <input autocomplete="on" name="api-key-user" type="text" value="${v.user}" placeholder="${(0, _index.getI18nText)('authentication.username')}" spellcheck="false" class="api-key-user" style="width:100px"> <input autocomplete="on" name="api-key-password" class="api-key-password fs-exclude ph-no-capture" data-hj-suppress data-sl="mask" type="password" value="${v.password}" placeholder="${(0, _index.getI18nText)('authentication.password')}" spellcheck="false" style="width:100px;margin:0 5px"> <button type="submit" class="m-btn thin-border" @click="${e => { onUserEnteredNewApiKeyValue.call(this, v.apiKeyId, e); }}" part="btn btn-outline"> ${v.finalKeyValue ? (0, _index.getI18nText)('authentication.update') : (0, _index.getI18nText)('authentication.set')} </button> </form> </div>`; } if (v.type.toLowerCase() === 'oauth2' && Object.keys(v.flows).length) { return (0, _lit.html)`${Object.keys(v.flows).map(f => oAuthFlowTemplate.call(this, f, v, v.flows[f]))}`; } return ''; } function securitySchemeTemplate() { const schemes = this.resolvedSpec && this.resolvedSpec.securitySchemes; if (!schemes) { return undefined; } const providedApiKeys = schemes.filter(v => v.finalKeyValue); return (0, _lit.html)` <section id="auth" part="section-auth" class="observe-me ${this.renderStyle === 'focused' ? 'section-gap--focused-mode' : 'section-gap'}"> <slot name="authentication"> <div class="section-padding"> <slot name="authentication-header"> <div class="sub-title regular-font" role="heading" aria-level="2">${(0, _index.getI18nText)('headers.authentication')}</div> </slot> <div class="small-font-size" style="display:flex;align-items:center;min-height:40px"> ${providedApiKeys.length > 0 ? (0, _lit.html)` <div class="blue-text"> ${providedApiKeys.length} API key applied </div> <div style="flex:1"></div> <button class="m-btn thin-border" part="btn btn-outline" @click="${() => { onClearAllApiKeys.call(this); }}">${(0, _index.getI18nText)('authentication.clear')}</button>` : (0, _lit.html)`<div class="red-text">${(0, _index.getI18nText)('authentication.no-api-key-applied')}</div>`} </div> ${schemes.length > 0 ? (0, _lit.html)` <table role="presentation" class="m-table" style="width:100%"> ${schemes.map(v => (0, _lit.html)` <tr> <td colspan="1" style="max-width:500px;overflow-wrap:break-word"> <div style="min-height:24px;display:flex;flex-direction:column;justify-content:center;align-items:center"> <div style="display:flex;justify-content:center"> <span style="font-weight:700">${getTypeDisplayHeader(v)}</span> </div> </div> ${v.description ? (0, _lit.html)` <div class="m-markdown"> ${(0, _unsafeHtml.unsafeHTML)((0, _commonUtils.toMarkdown)(v.description || ''))} </div>` : ''} </td> <td colspan="3">${renderSecurityScheme.call(this, v)}</td> </tr>`)} </table>` : ''} <slot name="authentication-footer"></slot> </div> </slot> </section> `; } function getOauthScopeTemplate(rawScopes) { const scopes = Array.isArray(rawScopes) ? rawScopes.map(s => s === null || s === void 0 ? void 0 : s.trim()).filter(s => s) : []; if (!scopes.length) { return ''; } return (0, _lit.html)` <div> <b>Required scopes:</b> <br> <div style="margin-left:8px"> ${scopes.map(scope => (0, _lit.html)`<span>${scope}</span>&nbsp;`)} </div> </div>`; } function getTypeDisplayHeader(securityScheme) { if (securityScheme.type === 'apiKey') { return `API Key (${securityScheme.name})`; } if (securityScheme.type === 'oauth2') { return 'OAuth2.0'; } if (securityScheme.type === 'http') { return securityScheme.scheme === 'basic' ? (0, _index.getI18nText)('authentication.http-basic') : 'HTTP Bearer'; } return securityScheme.type; } function pathSecurityTemplate(pathSecurityOptions) { const requiredSecurityOptions = (pathSecurityOptions === null || pathSecurityOptions === void 0 ? void 0 : pathSecurityOptions.filter(o => o && Object.keys(o).length)) || []; if (this.resolvedSpec.securitySchemes && requiredSecurityOptions.length) { const orSecurityKeys1 = []; requiredSecurityOptions.forEach(pSecurity => { const andSecurityKeys1 = []; const andKeyTypes = []; Object.keys(pSecurity).forEach(pathSecurityKey => { const s = this.resolvedSpec.securitySchemes.find(ss => ss.apiKeyId === pathSecurityKey); andKeyTypes.push(s ? getTypeDisplayHeader(s) : pathSecurityKey); andSecurityKeys1.push({ ...s, scopes: pSecurity[pathSecurityKey] }); }); orSecurityKeys1.push({ securityTypes: andKeyTypes.length > 1 ? `${andKeyTypes[0]} + ${andKeyTypes.length - 1} more` : andKeyTypes[0], securityDefs: andSecurityKeys1 }); }); return (0, _lit.html)`<div class="security-info-button" data-content-id="auth" @click="${e => this.scrollToEventTarget(e, false)}"> <div style="position:relative;display:flex;min-width:350px;max-width:700px;justify-content:flex-end"> <svg width="16" height="24" style="cursor:pointer"> <g> <path style="fill:var(--fg3)" d="m13.8,8.5l0,-2.6l0,0c0,-3.2 -2.6,-5.8 -5.8,-5.8s-5.8,2.6 -5.8,5.8l0,0l0,2.6l-2.1,0l0,11.2l16,0l0,-11.2l-2.1,0l-0,0l0,0l0,0l-0,0zm-9.8,-2.6c0,0 0,0 0,0c0,-2.2 1.8,-4 4,-4c2.2,0 4,1.8 4,4c0,0 0,0 0,0l0,2.6l-8.03,0l0,-2.6l0,0l0,0z"/> </g> </svg> ${orSecurityKeys1.map((orSecurityItem1, i) => (0, _lit.html)` ${i !== 0 ? (0, _lit.html)`<div style="padding:3px 4px"> OR </div>` : ''} <div class="security-tooltip tooltip" style="cursor:pointer"> <div style="padding:2px 4px;white-space:nowrap;text-overflow:ellipsis;max-width:150px;overflow:hidden"> <span part="anchor anchor-operation-security"> ${orSecurityItem1.securityTypes} </span> </div> <div class="tooltip-text" style="position:absolute;color:var(--fg);top:26px;right:0;border:1px solid var(--border-color);padding:2px 4px;display:block"> ${orSecurityItem1.securityDefs.length > 1 ? (0, _lit.html)`<div>Requires <b>all</b> of the following </div>` : ''} <div style="padding-left:8px"> ${orSecurityItem1.securityDefs.map((andSecurityItem, j) => (0, _lit.html)` ${andSecurityItem.type === 'oauth2' ? (0, _lit.html)` <div> ${orSecurityItem1.securityDefs.length > 1 ? (0, _lit.html)`<b>${j + 1}.</b> &nbsp;` : (0, _lit.html)`Requires`} OAuth token (${andSecurityItem.apiKeyId}) in <b>Authorization header</b> ${getOauthScopeTemplate(andSecurityItem.scopes)} </div>` : andSecurityItem.type === 'http' ? (0, _lit.html)` <div> ${orSecurityItem1.securityDefs.length > 1 ? (0, _lit.html)`<b>${j + 1}.</b> &nbsp;` : (0, _lit.html)`${(0, _index.getI18nText)('authentication.requires')}`} ${andSecurityItem.scheme === 'basic' ? (0, _index.getI18nText)('authentication.http-basic-note') : 'Bearer Token'} ${(0, _index.getI18nText)('authentication.in-auth-header')} ${getOauthScopeTemplate(andSecurityItem.scopes)} </div>` : (0, _lit.html)` <div> ${orSecurityItem1.securityDefs.length > 1 ? (0, _lit.html)`<b>${j + 1}.</b> &nbsp;` : (0, _lit.html)`Requires`} Token in <b>${andSecurityItem.name} ${andSecurityItem.in}</b> ${getOauthScopeTemplate(andSecurityItem.scopes)} </div>`} `)} </div> </div> </div> `)} </div> </div>`; } return ''; } /* eslint-enable indent */