@scalar/api-client 3.13.7 → 3.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/README.md +2 -1
- package/dist/style.css +98 -83
- package/dist/v2/blocks/request-block/RequestBlock.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.d.ts +6 -6
- package/dist/v2/blocks/request-block/components/RequestBody.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.js +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js +72 -11
- package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestBodyStructured.vue.d.ts +19 -0
- package/dist/v2/blocks/request-block/components/RequestBodyStructured.vue.d.ts.map +1 -0
- package/dist/v2/blocks/request-block/components/RequestBodyStructured.vue.js +7 -0
- package/dist/v2/blocks/request-block/components/RequestBodyStructured.vue.js.map +1 -0
- package/dist/v2/blocks/request-block/components/RequestBodyStructured.vue.script.js +81 -0
- package/dist/v2/blocks/request-block/components/RequestBodyStructured.vue.script.js.map +1 -0
- package/dist/v2/blocks/request-block/components/RequestBodyViewToggle.vue.d.ts +13 -0
- package/dist/v2/blocks/request-block/components/RequestBodyViewToggle.vue.d.ts.map +1 -0
- package/dist/v2/blocks/request-block/components/RequestBodyViewToggle.vue.js +7 -0
- package/dist/v2/blocks/request-block/components/RequestBodyViewToggle.vue.js.map +1 -0
- package/dist/v2/blocks/request-block/components/RequestBodyViewToggle.vue.script.js +34 -0
- package/dist/v2/blocks/request-block/components/RequestBodyViewToggle.vue.script.js.map +1 -0
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.js.map +1 -1
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js +8 -2
- package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/fold-structured-body-rows.d.ts +17 -0
- package/dist/v2/blocks/request-block/helpers/fold-structured-body-rows.d.ts.map +1 -0
- package/dist/v2/blocks/request-block/helpers/fold-structured-body-rows.js +33 -0
- package/dist/v2/blocks/request-block/helpers/fold-structured-body-rows.js.map +1 -0
- package/dist/v2/blocks/request-block/helpers/get-form-body-rows.d.ts +28 -0
- package/dist/v2/blocks/request-block/helpers/get-form-body-rows.d.ts.map +1 -1
- package/dist/v2/blocks/request-block/helpers/get-form-body-rows.js +2 -2
- package/dist/v2/blocks/request-block/helpers/get-form-body-rows.js.map +1 -1
- package/dist/v2/blocks/request-block/helpers/get-structured-body-rows.d.ts +13 -0
- package/dist/v2/blocks/request-block/helpers/get-structured-body-rows.d.ts.map +1 -0
- package/dist/v2/blocks/request-block/helpers/get-structured-body-rows.js +39 -0
- package/dist/v2/blocks/request-block/helpers/get-structured-body-rows.js.map +1 -0
- package/dist/v2/blocks/request-block/helpers/structured-body-codec.d.ts +15 -0
- package/dist/v2/blocks/request-block/helpers/structured-body-codec.d.ts.map +1 -0
- package/dist/v2/blocks/request-block/helpers/structured-body-codec.js +33 -0
- package/dist/v2/blocks/request-block/helpers/structured-body-codec.js.map +1 -0
- package/dist/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.d.ts +18 -2
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.script.js +18 -13
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuthScopesInput.vue.d.ts +6 -2
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuthScopesInput.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuthScopesInput.vue.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuthScopesInput.vue.script.js +16 -8
- package/dist/v2/blocks/scalar-auth-selector-block/components/OAuthScopesInput.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.d.ts +7 -3
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js +338 -25
- package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.js +7 -11
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/run-oauth2-authorize.d.ts +42 -0
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/run-oauth2-authorize.d.ts.map +1 -0
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/run-oauth2-authorize.js +60 -0
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/run-oauth2-authorize.js.map +1 -0
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/security-scheme.d.ts +17 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/security-scheme.d.ts.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/security-scheme.js +33 -1
- package/dist/v2/blocks/scalar-auth-selector-block/helpers/security-scheme.js.map +1 -1
- package/dist/v2/components/data-table/DataTableCheckbox.vue.d.ts +2 -0
- package/dist/v2/components/data-table/DataTableCheckbox.vue.d.ts.map +1 -1
- package/dist/v2/components/data-table/DataTableCheckbox.vue.js.map +1 -1
- package/dist/v2/components/data-table/DataTableCheckbox.vue.script.js +8 -2
- package/dist/v2/components/data-table/DataTableCheckbox.vue.script.js.map +1 -1
- package/dist/v2/constants.js +1 -1
- package/dist/vue-styles.css +1 -1
- package/package.json +10 -10
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { WorkspaceEventBus } from '@scalar/workspace-store/events';
|
|
2
|
-
import type
|
|
2
|
+
import { type MergedSecuritySchemes } from '@scalar/workspace-store/request-example';
|
|
3
3
|
import type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments';
|
|
4
4
|
import type { SecurityRequirementObject, ServerObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document';
|
|
5
5
|
import { type OAuth2Options } from './OAuth2.vue.js';
|
|
@@ -27,7 +27,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
27
27
|
"update:selectedScopes": (payload: Omit<{
|
|
28
28
|
id: string[];
|
|
29
29
|
name: string;
|
|
30
|
-
scopes
|
|
30
|
+
scopes?: string[];
|
|
31
|
+
scope?: string;
|
|
32
|
+
selected?: boolean;
|
|
31
33
|
meta: import("@scalar/workspace-store/events").AuthMeta;
|
|
32
34
|
}, "meta">) => any;
|
|
33
35
|
"upsert:scope": (payload: {
|
|
@@ -47,7 +49,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
47
49
|
"onUpdate:selectedScopes"?: ((payload: Omit<{
|
|
48
50
|
id: string[];
|
|
49
51
|
name: string;
|
|
50
|
-
scopes
|
|
52
|
+
scopes?: string[];
|
|
53
|
+
scope?: string;
|
|
54
|
+
selected?: boolean;
|
|
51
55
|
meta: import("@scalar/workspace-store/events").AuthMeta;
|
|
52
56
|
}, "meta">) => any) | undefined;
|
|
53
57
|
"onUpsert:scope"?: ((payload: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RequestAuthTab.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RequestAuthTab.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue"],"names":[],"mappings":"AA4yBA,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,gCAAgC,CAAA;AAEvC,OAAO,EAML,KAAK,qBAAqB,EAI3B,MAAM,yCAAyC,CAAA;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AAEnH,OAAO,KAAK,EAEV,yBAAyB,EACzB,YAAY,EACb,MAAM,8DAA8D,CAAA;AAerE,OAAe,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AAUzD,KAAK,WAAW,GAAG;IACjB,wCAAwC;IACxC,WAAW,EAAE,kBAAkB,CAAA;IAC/B,yFAAyF;IACzF,QAAQ,EAAE,OAAO,CAAA;IACjB,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,+BAA+B;IAC/B,uBAAuB,EAAE,yBAAyB,CAAA;IAClD,oGAAoG;IACpG,eAAe,EAAE,qBAAqB,CAAA;IACtC,mCAAmC;IACnC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;IAC3B,2CAA2C;IAC3C,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,uDAAuD;IACvD,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,yFAAyF;IACzF,YAAY,CAAC,EAAE,SAAS,GAAG,UAAU,CAAA;CACtC,CAAC;AAg8CF,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RequestAuthTab.vue.js","names":[],"sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarMarkdownSummary } from '@scalar/components/markdown'\nimport type {\n SecretsApiKey,\n SecretsHttp,\n} from '@scalar/workspace-store/entities/auth'\nimport type {\n ApiReferenceEvents,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type {\n MergedSecuritySchemes,\n SecuritySchemeObjectSecret,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { getDocumentTypeLabel } from '@scalar/workspace-store/schemas/type-guards'\nimport type {\n ApiKeyObject,\n SecurityRequirementObject,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { capitalize, computed, ref } from 'vue'\n\nimport { DataTableCell, DataTableRow } from '@/v2/components/data-table'\n\nimport OAuth2, { type OAuth2Options } from './OAuth2.vue'\nimport OpenIDConnect from './OpenIDConnect.vue'\nimport RequestAuthDataTableInput from './RequestAuthDataTableInput.vue'\n\ntype SecurityItem = {\n scheme: SecuritySchemeObjectSecret | undefined\n name: string\n scopes: string[]\n}\n\nconst {\n environment,\n isStatic,\n proxyUrl,\n selectedSecuritySchemas,\n securitySchemes,\n server,\n eventBus,\n options,\n documentType = 'openapi',\n} = defineProps<{\n /** Current environment configuration */\n environment: XScalarEnvironment\n /** Controls the display of certain borders which are used when we are non-collapsible */\n isStatic: boolean\n /** Proxy URL */\n proxyUrl: string\n /** Selected security schemes*/\n selectedSecuritySchemas: SecurityRequirementObject\n /** Merged security schemes from the document and the config together with the auth store secrets */\n securitySchemes: MergedSecuritySchemes\n /** Current server configuration */\n server: ServerObject | null\n /** Event bus for authentication updates */\n eventBus: WorkspaceEventBus\n /** Any config options required for the OAuth2 flow */\n options?: OAuth2Options\n /** Type of the document the schemes belong to, used to label the missing-type warning */\n documentType?: 'openapi' | 'asyncapi'\n}>()\n\n/**\n * Human-readable name of the document type.\n * Used in the missing-type warning so it points at the correct document\n * (e.g. \"AsyncAPI\") instead of always naming OpenAPI.\n */\nconst documentTypeLabel = computed<string>(() =>\n getDocumentTypeLabel(documentType),\n)\n\nconst emits = defineEmits<{\n (\n e: 'update:selectedScopes',\n payload: Omit<ApiReferenceEvents['auth:update:selected-scopes'], 'meta'>,\n ): void\n (e: 'upsert:scope', payload: ApiReferenceEvents['auth:upsert:scopes']): void\n (e: 'delete:scope', payload: ApiReferenceEvents['auth:delete:scopes']): void\n}>()\n\n/**\n * Resolves security schemes from the OpenAPI document and combines them with their selected scopes.\n * Each item includes the scheme definition, name, and associated scopes.\n */\nconst security = computed<SecurityItem[]>(() =>\n Object.entries(selectedSecuritySchemas).map(([name, scopes = []]) => ({\n scheme: getResolvedRef(securitySchemes[name]),\n name,\n scopes,\n })),\n)\n\n/** Tracks which OAuth2 flow is currently active when multiple flows are available. */\nconst activeFlow = ref<string>('')\n\n/** Keeps the selected flow in sync with currently available flow keys. */\nconst selectedFlow = computed<string>(() => {\n const authFlowKeys = security.value.flatMap(({ scheme }) => {\n if (scheme?.type !== 'oauth2' && scheme?.type !== 'openIdConnect') {\n return []\n }\n\n return Object.keys(scheme.flows ?? {})\n })\n\n return authFlowKeys.includes(activeFlow.value) ? activeFlow.value : ''\n})\n\nconst setActiveFlow = (flow: string): void => {\n activeFlow.value = flow\n}\n\n/** Determines if multiple auth schemes are configured, which affects the UI layout. */\nconst hasMultipleSchemes = computed<boolean>(() => security.value.length > 1)\n\n/**\n * Generates a human-readable label for the security scheme.\n * Intentionally omits the description here — it is rendered separately as\n * rich text via ScalarMarkdownSummary so markdown formatting is preserved.\n */\nconst generateLabel = (\n name: string,\n scheme: SecuritySchemeObjectSecret,\n): string => {\n const capitalizedName = capitalize(name)\n\n switch (scheme.type) {\n case 'apiKey':\n return `${capitalizedName}: ${scheme.in}`\n\n case 'openIdConnect':\n case 'oauth2': {\n const firstFlow = Object.keys(scheme.flows ?? {})[0]\n const currentFlow = selectedFlow.value || firstFlow\n if (!currentFlow) {\n return capitalizedName\n }\n return `${capitalizedName}: ${currentFlow}`\n }\n\n case 'http':\n return `${capitalizedName}: ${scheme.scheme}`\n\n default:\n return capitalizedName\n }\n}\n\n/**\n * Whether an API key scheme exposes an editable parameter name.\n *\n * OpenAPI `apiKey` and AsyncAPI `httpApiKey` (normalized to `apiKey`) name a query/header/cookie\n * parameter, so the Name input is shown. AsyncAPI `apiKey` places the key in the broker `user` or\n * `password` slot and has no parameter name, so the Name input is hidden and only the value is asked for.\n */\nconst apiKeyHasName = (scheme: { in?: string }): boolean =>\n scheme.in !== 'user' && scheme.in !== 'password'\n\n/**\n * The scheme's type when it is one we do not render inputs for (e.g. AsyncAPI broker types like\n * `userPassword` or `scramSha256`). Read through a helper so the fallback template branch, where\n * the scheme type is narrowed to `never` after the supported cases, can still surface the type.\n */\nconst getUnsupportedSchemeType = (\n scheme: SecurityItem['scheme'],\n): string | undefined => scheme?.type\n\n/**\n * Determines if an OAuth2 flow tab should be active.\n * The first flow is active by default if no flow is explicitly selected.\n */\nconst isFlowActive = (flowKey: string, index: number): boolean =>\n selectedFlow.value === flowKey || (index === 0 && !selectedFlow.value)\n\n/** Computes the container class for static display mode. */\nconst getStaticBorderClass = (): string | false => isStatic && 'border-t'\n\nconst handleHttpSecretsUpdate = (\n payload: Omit<Partial<SecretsHttp>, 'type'>,\n name: string,\n): void =>\n eventBus.emit('auth:update:security-scheme-secrets', {\n payload: { type: 'http', ...payload },\n name,\n })\n\nconst handleApiKeySecretsUpdate = (\n payload: Omit<Partial<SecretsApiKey>, 'type'>,\n name: string,\n): void =>\n eventBus.emit('auth:update:security-scheme-secrets', {\n payload: { type: 'apiKey', ...payload },\n name,\n })\n\nconst handleApiKeySecuritySchemeUpdate = (\n payload: Omit<Partial<ApiKeyObject>, 'type'>,\n name: string,\n): void =>\n eventBus.emit('auth:update:security-scheme', {\n payload: { type: 'apiKey', ...payload },\n name,\n })\n\n/** Handles scope selection updates for OAuth2 */\nconst handleScopesUpdate = (\n name: string,\n event: { scopes: string[] },\n): void => {\n emits('update:selectedScopes', {\n id: Object.keys(selectedSecuritySchemas),\n name,\n ...event,\n })\n}\n\n/** Handles scope-definition upserts (add / rename / description change) */\nconst handleScopeUpsert = (\n name: string,\n event: Omit<ApiReferenceEvents['auth:upsert:scopes'], 'name'>,\n): void => {\n emits('upsert:scope', { ...event, name })\n}\n\n/** Handles scope-definition deletes */\nconst handleScopeDelete = (\n name: string,\n event: Omit<ApiReferenceEvents['auth:delete:scopes'], 'name'>,\n): void => {\n emits('delete:scope', { ...event, name })\n}\n\n/**\n * Computes dynamic classes for OAuth2 flow tabs based on active state.\n */\nconst getFlowTabClasses = (flowKey: string, index: number): string => {\n const baseClasses =\n 'floating-bg text-c-3 relative cursor-pointer border-b border-transparent py-1 text-base font-medium'\n const activeClasses = '!text-c-1 !rounded-none border-b !border-current'\n\n return isFlowActive(flowKey, index)\n ? `${baseClasses} ${activeClasses} ${isStatic ? 'opacity-100' : ''}`\n : baseClasses\n}\n</script>\n<template>\n <template\n v-for=\"{ scheme, name, scopes } in security\"\n :key=\"name\">\n <!--\n Header row for AND'ed schemes: label (bold) and description (rich text) are\n combined.\n -->\n <DataTableRow v-if=\"hasMultipleSchemes && scheme\">\n <DataTableCell\n :aria-label=\"generateLabel(name, scheme)\"\n class=\"max-h-[auto]\">\n <div class=\"bg-b-1 min-w-0 flex-1 px-3 py-1.25\">\n <p class=\"text-c-1 leading-5.5 font-medium\">\n {{ generateLabel(name, scheme) }}\n </p>\n <ScalarMarkdownSummary\n v-if=\"scheme.description\"\n class=\"auth-description text-c-2 w-full\"\n :value=\"scheme.description\" />\n </div>\n </DataTableCell>\n </DataTableRow>\n\n <!-- Description: shown for single auth schemes with descriptions -->\n <DataTableRow v-if=\"scheme?.description && !hasMultipleSchemes\">\n <DataTableCell\n :aria-label=\"scheme.description\"\n class=\"max-h-[auto]\">\n <ScalarMarkdownSummary\n class=\"auth-description bg-b-1 text-c-2 min-w-0 flex-1 px-3 py-1.25\"\n :value=\"scheme.description\" />\n </DataTableCell>\n </DataTableRow>\n\n <!-- HTTP Authentication -->\n <template v-if=\"scheme?.type === 'http'\">\n <!-- Bearer Token -->\n <DataTableRow v-if=\"scheme.scheme === 'bearer'\">\n <RequestAuthDataTableInput\n :containerClass=\"getStaticBorderClass()\"\n :environment\n :modelValue=\"scheme['x-scalar-secret-token']\"\n placeholder=\"Token\"\n type=\"password\"\n @update:modelValue=\"\n (v) => handleHttpSecretsUpdate({ 'x-scalar-secret-token': v }, name)\n \">\n Bearer Token\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <!-- HTTP Basic Authentication -->\n <template v-else-if=\"scheme?.scheme === 'basic'\">\n <DataTableRow>\n <RequestAuthDataTableInput\n class=\"text-c-2\"\n :environment\n :modelValue=\"scheme['x-scalar-secret-username']\"\n placeholder=\"janedoe\"\n required\n @update:modelValue=\"\n (v) =>\n handleHttpSecretsUpdate({ 'x-scalar-secret-username': v }, name)\n \">\n Username\n </RequestAuthDataTableInput>\n </DataTableRow>\n <DataTableRow>\n <RequestAuthDataTableInput\n :environment\n :modelValue=\"scheme['x-scalar-secret-password']\"\n placeholder=\"********\"\n type=\"password\"\n @update:modelValue=\"\n (v) =>\n handleHttpSecretsUpdate({ 'x-scalar-secret-password': v }, name)\n \">\n Password\n </RequestAuthDataTableInput>\n </DataTableRow>\n </template>\n </template>\n\n <!-- API Key Authentication -->\n <template v-else-if=\"scheme?.type === 'apiKey'\">\n <DataTableRow v-if=\"apiKeyHasName(scheme)\">\n <RequestAuthDataTableInput\n :containerClass=\"getStaticBorderClass()\"\n :environment\n :modelValue=\"scheme.name\"\n placeholder=\"api-key\"\n @update:modelValue=\"\n (v) => handleApiKeySecuritySchemeUpdate({ name: v }, name)\n \">\n Name\n </RequestAuthDataTableInput>\n </DataTableRow>\n <DataTableRow>\n <RequestAuthDataTableInput\n :containerClass=\"\n apiKeyHasName(scheme) ? undefined : getStaticBorderClass()\n \"\n :environment\n :modelValue=\"scheme['x-scalar-secret-token']\"\n placeholder=\"QUxMIFlPVVIgQkFTRSBBUkUgQkVMT05HIFRPIFVT\"\n type=\"password\"\n @update:modelValue=\"\n (v) =>\n handleApiKeySecretsUpdate({ 'x-scalar-secret-token': v }, name)\n \">\n Value\n </RequestAuthDataTableInput>\n </DataTableRow>\n </template>\n\n <!-- OAuth 2.0 / OpenID Connect Authentication -->\n <template\n v-else-if=\"scheme?.type === 'oauth2' || scheme?.type === 'openIdConnect'\">\n <!-- OpenID Connect -->\n <OpenIDConnect\n v-if=\"\n scheme?.type === 'openIdConnect' &&\n !Object.keys(scheme.flows ?? {}).length\n \"\n :customFetch=\"options?.customFetch\"\n :environment\n :eventBus\n :getStaticBorderClass\n :name\n :proxyUrl\n :scheme />\n\n <!-- Flow selector tabs: shown when multiple flows are available -->\n <DataTableRow v-if=\"Object.keys(scheme.flows ?? {}).length > 1\">\n <div class=\"flex min-h-8 border-t text-base\">\n <div class=\"flex h-8 max-w-full gap-2.5 overflow-x-auto px-3\">\n <button\n v-for=\"(_, key, ind) in scheme.flows\"\n :key=\"key\"\n :class=\"getFlowTabClasses(key, ind)\"\n type=\"button\"\n @click=\"setActiveFlow(key)\">\n <span class=\"relative z-10\">{{ key }}</span>\n </button>\n </div>\n </div>\n </DataTableRow>\n\n <!-- OAuth2 flow configuration -->\n <template\n v-for=\"(_flow, key, ind) in scheme.flows\"\n :key=\"key\">\n <OAuth2\n v-if=\"scheme.flows && isFlowActive(key, ind)\"\n :environment\n :eventBus\n :flows=\"scheme.flows\"\n :name\n :options\n :proxyUrl\n :scheme\n :selectedScopes=\"scopes\"\n :server\n :type=\"key\"\n @delete:scope=\"(event) => handleScopeDelete(name, event)\"\n @update:selectedScopes=\"(event) => handleScopesUpdate(name, event)\"\n @upsert:scope=\"(event) => handleScopeUpsert(name, event)\" />\n </template>\n </template>\n\n <!-- Scheme has a type we do not render inputs for yet (e.g. AsyncAPI broker types) -->\n <div\n v-else-if=\"getUnsupportedSchemeType(scheme)\"\n class=\"text-c-3 flex items-center justify-center border-t p-4 px-4 text-center text-xs text-balance\">\n The <code>{{ getUnsupportedSchemeType(scheme) }}</code> security scheme\n type is not supported yet.\n </div>\n\n <!-- Scheme is missing type -->\n <div\n v-else\n class=\"text-c-3 flex items-center justify-center border-t p-4 px-4 text-center text-xs text-balance\">\n The security scheme is missing a type, please double check your\n {{ documentTypeLabel }} document or Authentication Configuration\n </div>\n </template>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"RequestAuthTab.vue.js","names":[],"sources":["../../../../../src/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarIconButton } from '@scalar/components/icon-button'\nimport { useLoadingState } from '@scalar/components/loading'\nimport { ScalarMarkdownSummary } from '@scalar/components/markdown'\nimport { ScalarModal, useModal } from '@scalar/components/modal'\nimport { ScalarIconGear } from '@scalar/icons'\nimport { useToasts } from '@scalar/use-toasts'\nimport type {\n SecretsApiKey,\n SecretsHttp,\n} from '@scalar/workspace-store/entities/auth'\nimport type {\n ApiReferenceEvents,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport {\n getEnvironmentVariables,\n isEncryptionSchemeType,\n isSaslSchemeType,\n type EncryptionObjectSecret,\n type GssapiObjectSecret,\n type MergedSecuritySchemes,\n type SaslObjectSecret,\n type SecuritySchemeObjectSecret,\n type X509ObjectSecret,\n} from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { getDocumentTypeLabel } from '@scalar/workspace-store/schemas/type-guards'\nimport type {\n ApiKeyObject,\n SecurityRequirementObject,\n ServerObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { capitalize, computed, ref } from 'vue'\n\nimport { refreshOauth2Token } from '@/v2/blocks/scalar-auth-selector-block/helpers/oauth'\nimport {\n runOAuth2Authorize,\n storeOAuth2Tokens,\n} from '@/v2/blocks/scalar-auth-selector-block/helpers/run-oauth2-authorize'\nimport { getOauth2AcquisitionTarget } from '@/v2/blocks/scalar-auth-selector-block/helpers/security-scheme'\nimport {\n DataTable,\n DataTableCell,\n DataTableRow,\n} from '@/v2/components/data-table'\n\nimport OAuth2, { type OAuth2Options } from './OAuth2.vue'\nimport OpenIDConnect from './OpenIDConnect.vue'\nimport RequestAuthDataTableInput from './RequestAuthDataTableInput.vue'\n\ntype SecurityItem = {\n scheme: SecuritySchemeObjectSecret | undefined\n name: string\n scopes: string[]\n}\n\nconst {\n environment,\n isStatic,\n proxyUrl,\n selectedSecuritySchemas,\n securitySchemes,\n server,\n eventBus,\n options,\n documentType = 'openapi',\n} = defineProps<{\n /** Current environment configuration */\n environment: XScalarEnvironment\n /** Controls the display of certain borders which are used when we are non-collapsible */\n isStatic: boolean\n /** Proxy URL */\n proxyUrl: string\n /** Selected security schemes*/\n selectedSecuritySchemas: SecurityRequirementObject\n /** Merged security schemes from the document and the config together with the auth store secrets */\n securitySchemes: MergedSecuritySchemes\n /** Current server configuration */\n server: ServerObject | null\n /** Event bus for authentication updates */\n eventBus: WorkspaceEventBus\n /** Any config options required for the OAuth2 flow */\n options?: OAuth2Options\n /** Type of the document the schemes belong to, used to label the missing-type warning */\n documentType?: 'openapi' | 'asyncapi'\n}>()\n\n/**\n * Human-readable name of the document type.\n * Used in the missing-type warning so it points at the correct document\n * (e.g. \"AsyncAPI\") instead of always naming OpenAPI.\n */\nconst documentTypeLabel = computed<string>(() =>\n getDocumentTypeLabel(documentType),\n)\n\nconst emits = defineEmits<{\n (\n e: 'update:selectedScopes',\n payload: Omit<ApiReferenceEvents['auth:update:selected-scopes'], 'meta'>,\n ): void\n (e: 'upsert:scope', payload: ApiReferenceEvents['auth:upsert:scopes']): void\n (e: 'delete:scope', payload: ApiReferenceEvents['auth:delete:scopes']): void\n}>()\n\n/**\n * Resolves security schemes from the OpenAPI document and combines them with their selected scopes.\n * Each item includes the scheme definition, name, and associated scopes.\n */\nconst security = computed<SecurityItem[]>(() =>\n Object.entries(selectedSecuritySchemas).map(([name, scopes = []]) => ({\n scheme: getResolvedRef(securitySchemes[name]),\n name,\n scopes,\n })),\n)\n\n/** Tracks which OAuth2 flow is currently active when multiple flows are available. */\nconst activeFlow = ref<string>('')\n\n/** Keeps the selected flow in sync with currently available flow keys. */\nconst selectedFlow = computed<string>(() => {\n const authFlowKeys = security.value.flatMap(({ scheme }) => {\n if (scheme?.type !== 'oauth2' && scheme?.type !== 'openIdConnect') {\n return []\n }\n\n return Object.keys(scheme.flows ?? {})\n })\n\n return authFlowKeys.includes(activeFlow.value) ? activeFlow.value : ''\n})\n\nconst setActiveFlow = (flow: string): void => {\n activeFlow.value = flow\n}\n\n/** Determines if multiple auth schemes are configured, which affects the UI layout. */\nconst hasMultipleSchemes = computed<boolean>(() => security.value.length > 1)\n\n/**\n * Generates a human-readable label for the security scheme.\n * Intentionally omits the description here — it is rendered separately as\n * rich text via ScalarMarkdownSummary so markdown formatting is preserved.\n */\nconst generateLabel = (\n name: string,\n scheme: SecuritySchemeObjectSecret,\n): string => {\n const capitalizedName = capitalize(name)\n\n switch (scheme.type) {\n case 'apiKey':\n return `${capitalizedName}: ${scheme.in}`\n\n case 'openIdConnect':\n case 'oauth2': {\n const firstFlow = Object.keys(scheme.flows ?? {})[0]\n const currentFlow = selectedFlow.value || firstFlow\n if (!currentFlow) {\n return capitalizedName\n }\n return `${capitalizedName}: ${currentFlow}`\n }\n\n case 'http':\n return `${capitalizedName}: ${scheme.scheme}`\n\n default:\n return capitalizedName\n }\n}\n\n/**\n * Whether an API key scheme exposes an editable parameter name.\n *\n * OpenAPI `apiKey` and AsyncAPI `httpApiKey` (normalized to `apiKey`) name a query/header/cookie\n * parameter, so the Name input is shown. AsyncAPI `apiKey` places the key in the broker `user` or\n * `password` slot and has no parameter name, so the Name input is hidden and only the value is asked for.\n */\nconst apiKeyHasName = (scheme: { in?: string }): boolean =>\n scheme.in !== 'user' && scheme.in !== 'password'\n\n/**\n * SASL-style AsyncAPI broker schemes (`userPassword`, `plain`, `scramSha256`, `scramSha512`):\n * they all authenticate with a username + password pair, so they share one form.\n */\nconst isSaslScheme = (\n scheme: SecurityItem['scheme'],\n): scheme is SaslObjectSecret => isSaslSchemeType(scheme?.type)\n\n/** AsyncAPI encryption broker schemes: a single key value. */\nconst isEncryptionScheme = (\n scheme: SecurityItem['scheme'],\n): scheme is EncryptionObjectSecret => isEncryptionSchemeType(scheme?.type)\n\n/** AsyncAPI X509 broker scheme: a client certificate + private key pair (PEM). */\nconst isX509Scheme = (\n scheme: SecurityItem['scheme'],\n): scheme is X509ObjectSecret => scheme?.type === 'X509'\n\n/** AsyncAPI GSSAPI (Kerberos) broker scheme: the service name the client authenticates against. */\nconst isGssapiScheme = (\n scheme: SecurityItem['scheme'],\n): scheme is GssapiObjectSecret => scheme?.type === 'gssapi'\n\n/**\n * The scheme's type when it is one we do not render inputs for (a type outside both the OpenAPI\n * and AsyncAPI security scheme unions). Read through a helper so the fallback template branch,\n * where the scheme type is narrowed to `never` after the supported cases, can still surface the type.\n */\nconst getUnsupportedSchemeType = (\n scheme: SecurityItem['scheme'],\n): string | undefined => scheme?.type\n\n/**\n * Determines if an OAuth2 flow tab should be active.\n * The first flow is active by default if no flow is explicitly selected.\n */\nconst isFlowActive = (flowKey: string, index: number): boolean =>\n selectedFlow.value === flowKey || (index === 0 && !selectedFlow.value)\n\n/** Computes the container class for static display mode. */\nconst getStaticBorderClass = (): string | false => isStatic && 'border-t'\n\nconst handleHttpSecretsUpdate = (\n payload: Omit<Partial<SecretsHttp>, 'type'>,\n name: string,\n): void =>\n eventBus.emit('auth:update:security-scheme-secrets', {\n payload: { type: 'http', ...payload },\n name,\n })\n\nconst handleApiKeySecretsUpdate = (\n payload: Omit<Partial<SecretsApiKey>, 'type'>,\n name: string,\n): void =>\n eventBus.emit('auth:update:security-scheme-secrets', {\n payload: { type: 'apiKey', ...payload },\n name,\n })\n\n/**\n * AsyncAPI broker credentials (SASL, X509, encryption, GSSAPI) all persist through the same\n * event; only the secret key and scheme type differ, so they share one handler. The caller passes\n * a payload that already carries the narrowed scheme `type`.\n */\nconst handleBrokerSecretsUpdate = (\n payload: ApiReferenceEvents['auth:update:security-scheme-secrets']['payload'],\n name: string,\n): void =>\n eventBus.emit('auth:update:security-scheme-secrets', {\n payload,\n name,\n })\n\nconst handleApiKeySecuritySchemeUpdate = (\n payload: Omit<Partial<ApiKeyObject>, 'type'>,\n name: string,\n): void =>\n eventBus.emit('auth:update:security-scheme', {\n payload: { type: 'apiKey', ...payload },\n name,\n })\n\n/** Handles scope selection updates for OAuth2 */\nconst handleScopesUpdate = (\n name: string,\n event: { scopes?: string[]; scope?: string; selected?: boolean },\n): void => {\n emits('update:selectedScopes', {\n id: Object.keys(selectedSecuritySchemas),\n name,\n ...event,\n })\n}\n\n/** Handles scope-definition upserts (add / rename / description change) */\nconst handleScopeUpsert = (\n name: string,\n event: Omit<ApiReferenceEvents['auth:upsert:scopes'], 'name'>,\n): void => {\n emits('upsert:scope', { ...event, name })\n}\n\n/** Handles scope-definition deletes */\nconst handleScopeDelete = (\n name: string,\n event: Omit<ApiReferenceEvents['auth:delete:scopes'], 'name'>,\n): void => {\n emits('delete:scope', { ...event, name })\n}\n\n/**\n * Computes dynamic classes for OAuth2 flow tabs based on active state.\n */\nconst getFlowTabClasses = (flowKey: string, index: number): string => {\n const baseClasses =\n 'floating-bg text-c-3 relative cursor-pointer border-b border-transparent py-1 text-base font-medium'\n const activeClasses = '!text-c-1 !rounded-none border-b !border-current'\n\n return isFlowActive(flowKey, index)\n ? `${baseClasses} ${activeClasses} ${isStatic ? 'opacity-100' : ''}`\n : baseClasses\n}\n\n/**\n * OAuth2 token-acquisition target (an oauth2 scheme with an interactive grant) sourced from\n * the merged schemes. When the active scheme is HTTP bearer, this powers the inline\n * \"Authorize via OAuth2\" shortcut: the flow's bearer token is written onto the bearer scheme,\n * so the panel never switches to oauth2.\n *\n * The shortcut is purely a convenience, so it is offered for any interactive oauth2 scheme —\n * including one that is also independently selectable in the dropdown (e.g. Scalar Galaxy's\n * `oAuth2`). Whether that oauth2 scheme is *hidden* from the dropdown is a separate decision made\n * in the selector; here we only surface the shortcut.\n */\nconst oauth2Target = computed(() => getOauth2AcquisitionTarget(securitySchemes))\n\n/** Resolved oauth2 scheme object, for embedding its config form behind the gear. */\nconst oauth2Scheme = computed(() =>\n oauth2Target.value\n ? getResolvedRef(securitySchemes[oauth2Target.value.name])\n : undefined,\n)\n\nconst acquisitionLoader = useLoadingState()\nconst { toast } = useToasts()\nconst configModal = useModal()\n/** Bearer scheme that opened the config modal, so its Authorize callback targets it. */\nconst configBearerName = ref<string | undefined>()\n\n/** Runs the OAuth2 flow and writes the resulting bearer token onto the bearer scheme. */\nconst handleAcquisitionAuthorize = async (\n bearerName: string,\n): Promise<void> => {\n const target = oauth2Target.value\n if (!target || acquisitionLoader.isLoading) {\n return\n }\n acquisitionLoader.start()\n const [error] = await runOAuth2Authorize({\n eventBus,\n bearerSchemeName: bearerName,\n oauth2Name: target.name,\n flows: target.flows,\n flowType: target.flowType,\n scopes: target.scopes,\n server,\n proxyUrl,\n environment,\n options,\n })\n await acquisitionLoader.clear()\n if (error) {\n toast(error?.message ?? 'Failed to authorize', 'error')\n }\n}\n\n/** Refreshes the OAuth2 token and rewrites it onto the bearer scheme. */\nconst handleAcquisitionRefresh = async (bearerName: string): Promise<void> => {\n const target = oauth2Target.value\n // Only the authorization-code flow carries a refresh token; implicit can't be refreshed.\n if (\n !target ||\n target.flowType !== 'authorizationCode' ||\n acquisitionLoader.isLoading\n ) {\n return\n }\n acquisitionLoader.start()\n const [error, tokens] = await refreshOauth2Token(\n target.flows,\n target.flowType,\n proxyUrl,\n server,\n getEnvironmentVariables(environment),\n options?.customFetch,\n )\n await acquisitionLoader.clear()\n if (tokens?.accessToken) {\n storeOAuth2Tokens(eventBus, {\n bearerSchemeName: bearerName,\n oauth2Name: target.name,\n flowType: target.flowType,\n tokens,\n })\n } else if (error) {\n toast(error?.message ?? 'Failed to refresh', 'error')\n }\n}\n\nconst openAcquisitionConfig = (bearerName: string): void => {\n configBearerName.value = bearerName\n configModal.show()\n}\n\n/** Closes the config modal and runs Authorize against the bearer scheme that opened it. */\nconst handleConfigAuthorize = (): void => {\n const bearerName = configBearerName.value\n configModal.hide()\n if (bearerName) {\n void handleAcquisitionAuthorize(bearerName)\n }\n}\n</script>\n<template>\n <template\n v-for=\"{ scheme, name, scopes } in security\"\n :key=\"name\">\n <!--\n Header row for AND'ed schemes: label (bold) and description (rich text) are\n combined.\n -->\n <DataTableRow v-if=\"hasMultipleSchemes && scheme\">\n <DataTableCell\n :aria-label=\"generateLabel(name, scheme)\"\n class=\"max-h-[auto]\">\n <div class=\"bg-b-1 min-w-0 flex-1 px-3 py-1.25\">\n <p class=\"text-c-1 leading-5.5 font-medium\">\n {{ generateLabel(name, scheme) }}\n </p>\n <ScalarMarkdownSummary\n v-if=\"scheme.description\"\n class=\"auth-description text-c-2 w-full\"\n :value=\"scheme.description\" />\n </div>\n </DataTableCell>\n </DataTableRow>\n\n <!-- Description: shown for single auth schemes with descriptions -->\n <DataTableRow v-if=\"scheme?.description && !hasMultipleSchemes\">\n <DataTableCell\n :aria-label=\"scheme.description\"\n class=\"max-h-[auto]\">\n <ScalarMarkdownSummary\n class=\"auth-description bg-b-1 text-c-2 min-w-0 flex-1 px-3 py-1.25\"\n :value=\"scheme.description\" />\n </DataTableCell>\n </DataTableRow>\n\n <!-- HTTP Authentication -->\n <template v-if=\"scheme?.type === 'http'\">\n <!-- Bearer Token -->\n <DataTableRow v-if=\"scheme.scheme === 'bearer'\">\n <RequestAuthDataTableInput\n :containerClass=\"getStaticBorderClass()\"\n :environment\n :modelValue=\"scheme['x-scalar-secret-token']\"\n placeholder=\"Token\"\n type=\"password\"\n @update:modelValue=\"\n (v) => handleHttpSecretsUpdate({ 'x-scalar-secret-token': v }, name)\n \">\n Bearer Token\n </RequestAuthDataTableInput>\n </DataTableRow>\n\n <!-- OAuth2 token-acquisition shortcut (shown when an interactive oauth2 flow exists) -->\n <DataTableRow v-if=\"scheme.scheme === 'bearer' && oauth2Target\">\n <div class=\"flex h-8 items-center gap-2 border-t px-3\">\n <span class=\"text-c-3 mr-auto text-xs\">Get a token</span>\n <ScalarButton\n class=\"p-0 px-2 py-0.5\"\n :loader=\"acquisitionLoader\"\n size=\"sm\"\n type=\"button\"\n variant=\"outlined\"\n @click=\"handleAcquisitionAuthorize(name)\">\n Authorize via {{ oauth2Target.name }}\n </ScalarButton>\n <ScalarButton\n v-if=\"\n scheme['x-scalar-secret-token'] &&\n oauth2Target.flowType === 'authorizationCode'\n \"\n class=\"p-0 px-2 py-0.5\"\n :disabled=\"acquisitionLoader.isLoading\"\n size=\"sm\"\n type=\"button\"\n variant=\"outlined\"\n @click=\"handleAcquisitionRefresh(name)\">\n Refresh\n </ScalarButton>\n <ScalarIconButton\n :icon=\"ScalarIconGear\"\n :label=\"`Configure ${oauth2Target.name}`\"\n size=\"xs\"\n @click=\"openAcquisitionConfig(name)\" />\n </div>\n </DataTableRow>\n\n <!-- HTTP Basic Authentication -->\n <template v-else-if=\"scheme?.scheme === 'basic'\">\n <DataTableRow>\n <RequestAuthDataTableInput\n class=\"text-c-2\"\n :environment\n :modelValue=\"scheme['x-scalar-secret-username']\"\n placeholder=\"janedoe\"\n required\n @update:modelValue=\"\n (v) =>\n handleHttpSecretsUpdate({ 'x-scalar-secret-username': v }, name)\n \">\n Username\n </RequestAuthDataTableInput>\n </DataTableRow>\n <DataTableRow>\n <RequestAuthDataTableInput\n :environment\n :modelValue=\"scheme['x-scalar-secret-password']\"\n placeholder=\"********\"\n type=\"password\"\n @update:modelValue=\"\n (v) =>\n handleHttpSecretsUpdate({ 'x-scalar-secret-password': v }, name)\n \">\n Password\n </RequestAuthDataTableInput>\n </DataTableRow>\n </template>\n </template>\n\n <!-- API Key Authentication -->\n <template v-else-if=\"scheme?.type === 'apiKey'\">\n <DataTableRow v-if=\"apiKeyHasName(scheme)\">\n <RequestAuthDataTableInput\n :containerClass=\"getStaticBorderClass()\"\n :environment\n :modelValue=\"scheme.name\"\n placeholder=\"api-key\"\n @update:modelValue=\"\n (v) => handleApiKeySecuritySchemeUpdate({ name: v }, name)\n \">\n Name\n </RequestAuthDataTableInput>\n </DataTableRow>\n <DataTableRow>\n <RequestAuthDataTableInput\n :containerClass=\"\n apiKeyHasName(scheme) ? undefined : getStaticBorderClass()\n \"\n :environment\n :modelValue=\"scheme['x-scalar-secret-token']\"\n placeholder=\"QUxMIFlPVVIgQkFTRSBBUkUgQkVMT05HIFRPIFVT\"\n type=\"password\"\n @update:modelValue=\"\n (v) =>\n handleApiKeySecretsUpdate({ 'x-scalar-secret-token': v }, name)\n \">\n Value\n </RequestAuthDataTableInput>\n </DataTableRow>\n </template>\n\n <!-- OAuth 2.0 / OpenID Connect Authentication -->\n <template\n v-else-if=\"scheme?.type === 'oauth2' || scheme?.type === 'openIdConnect'\">\n <!-- OpenID Connect -->\n <OpenIDConnect\n v-if=\"\n scheme?.type === 'openIdConnect' &&\n !Object.keys(scheme.flows ?? {}).length\n \"\n :customFetch=\"options?.customFetch\"\n :environment\n :eventBus\n :getStaticBorderClass\n :name\n :proxyUrl\n :scheme />\n\n <!-- Flow selector tabs: shown when multiple flows are available -->\n <DataTableRow v-if=\"Object.keys(scheme.flows ?? {}).length > 1\">\n <div class=\"flex min-h-8 border-t text-base\">\n <div class=\"flex h-8 max-w-full gap-2.5 overflow-x-auto px-3\">\n <button\n v-for=\"(_, key, ind) in scheme.flows\"\n :key=\"key\"\n :class=\"getFlowTabClasses(key, ind)\"\n type=\"button\"\n @click=\"setActiveFlow(key)\">\n <span class=\"relative z-10\">{{ key }}</span>\n </button>\n </div>\n </div>\n </DataTableRow>\n\n <!-- OAuth2 flow configuration -->\n <template\n v-for=\"(_flow, key, ind) in scheme.flows\"\n :key=\"key\">\n <OAuth2\n v-if=\"scheme.flows && isFlowActive(key, ind)\"\n :environment\n :eventBus\n :flows=\"scheme.flows\"\n :name\n :options\n :proxyUrl\n :scheme\n :selectedScopes=\"scopes\"\n :server\n :type=\"key\"\n @delete:scope=\"(event) => handleScopeDelete(name, event)\"\n @update:selectedScopes=\"(event) => handleScopesUpdate(name, event)\"\n @upsert:scope=\"(event) => handleScopeUpsert(name, event)\" />\n </template>\n </template>\n\n <!-- SASL broker authentication (userPassword, plain, scramSha256, scramSha512) -->\n <template v-else-if=\"isSaslScheme(scheme)\">\n <DataTableRow>\n <RequestAuthDataTableInput\n class=\"text-c-2\"\n :containerClass=\"getStaticBorderClass()\"\n :environment\n :modelValue=\"scheme['x-scalar-secret-username']\"\n placeholder=\"janedoe\"\n required\n @update:modelValue=\"\n (v) =>\n handleBrokerSecretsUpdate(\n { 'type': scheme.type, 'x-scalar-secret-username': v },\n name,\n )\n \">\n Username\n </RequestAuthDataTableInput>\n </DataTableRow>\n <DataTableRow>\n <RequestAuthDataTableInput\n :environment\n :modelValue=\"scheme['x-scalar-secret-password']\"\n placeholder=\"********\"\n type=\"password\"\n @update:modelValue=\"\n (v) =>\n handleBrokerSecretsUpdate(\n { 'type': scheme.type, 'x-scalar-secret-password': v },\n name,\n )\n \">\n Password\n </RequestAuthDataTableInput>\n </DataTableRow>\n </template>\n\n <!-- X509 client certificate authentication -->\n <template v-else-if=\"isX509Scheme(scheme)\">\n <DataTableRow>\n <RequestAuthDataTableInput\n :containerClass=\"getStaticBorderClass()\"\n :environment\n :modelValue=\"scheme['x-scalar-secret-client-certificate']\"\n placeholder=\"-----BEGIN CERTIFICATE-----\"\n type=\"password\"\n @update:modelValue=\"\n (v) =>\n handleBrokerSecretsUpdate(\n {\n 'type': scheme.type,\n 'x-scalar-secret-client-certificate': v,\n },\n name,\n )\n \">\n Client Certificate\n </RequestAuthDataTableInput>\n </DataTableRow>\n <DataTableRow>\n <RequestAuthDataTableInput\n :environment\n :modelValue=\"scheme['x-scalar-secret-private-key']\"\n placeholder=\"-----BEGIN PRIVATE KEY-----\"\n type=\"password\"\n @update:modelValue=\"\n (v) =>\n handleBrokerSecretsUpdate(\n { 'type': scheme.type, 'x-scalar-secret-private-key': v },\n name,\n )\n \">\n Private Key\n </RequestAuthDataTableInput>\n </DataTableRow>\n </template>\n\n <!-- Symmetric / asymmetric encryption key -->\n <template v-else-if=\"isEncryptionScheme(scheme)\">\n <DataTableRow>\n <RequestAuthDataTableInput\n :containerClass=\"getStaticBorderClass()\"\n :environment\n :modelValue=\"scheme['x-scalar-secret-token']\"\n placeholder=\"********\"\n type=\"password\"\n @update:modelValue=\"\n (v) =>\n handleBrokerSecretsUpdate(\n { 'type': scheme.type, 'x-scalar-secret-token': v },\n name,\n )\n \">\n Key\n </RequestAuthDataTableInput>\n </DataTableRow>\n </template>\n\n <!-- GSSAPI (Kerberos) authentication -->\n <template v-else-if=\"isGssapiScheme(scheme)\">\n <DataTableRow>\n <RequestAuthDataTableInput\n :containerClass=\"getStaticBorderClass()\"\n :environment\n :modelValue=\"scheme['x-scalar-secret-service-name']\"\n placeholder=\"kafka\"\n @update:modelValue=\"\n (v) =>\n handleBrokerSecretsUpdate(\n { 'type': scheme.type, 'x-scalar-secret-service-name': v },\n name,\n )\n \">\n Service Name\n </RequestAuthDataTableInput>\n </DataTableRow>\n </template>\n\n <!-- Scheme has a type we do not render inputs for -->\n <div\n v-else-if=\"getUnsupportedSchemeType(scheme)\"\n class=\"text-c-3 flex items-center justify-center border-t p-4 px-4 text-center text-xs text-balance\">\n The <code>{{ getUnsupportedSchemeType(scheme) }}</code> security scheme\n type is not supported yet.\n </div>\n\n <!-- Scheme is missing type -->\n <div\n v-else\n class=\"text-c-3 flex items-center justify-center border-t p-4 px-4 text-center text-xs text-balance\">\n The security scheme is missing a type, please double check your\n {{ documentTypeLabel }} document or Authentication Configuration\n </div>\n </template>\n\n <!-- OAuth2 configuration modal (opened from the bearer scheme's gear) -->\n <ScalarModal\n v-if=\"oauth2Target && oauth2Scheme\"\n :state=\"configModal\"\n size=\"sm\"\n :title=\"`Configure ${oauth2Target.name}`\">\n <DataTable\n :columns=\"['']\"\n presentational>\n <OAuth2\n hideActions\n :environment\n :eventBus\n :flows=\"oauth2Target.flows\"\n :name=\"oauth2Target.name\"\n :options\n :proxyUrl\n :scheme=\"oauth2Scheme\"\n :selectedScopes=\"oauth2Target.scopes\"\n :server\n :type=\"oauth2Target.flowType\"\n @delete:scope=\"(event) => handleScopeDelete(oauth2Target!.name, event)\"\n @update:selectedScopes=\"\n (event) => handleScopesUpdate(oauth2Target!.name, event)\n \"\n @upsert:scope=\"\n (event) => handleScopeUpsert(oauth2Target!.name, event)\n \" />\n </DataTable>\n <div class=\"flex h-8 items-center justify-end gap-2 border-t\">\n <ScalarButton\n class=\"p-0 px-2 py-0.5\"\n size=\"sm\"\n variant=\"outlined\"\n @click=\"configModal.hide()\">\n Cancel\n </ScalarButton>\n <ScalarButton\n class=\"p-0 px-2 py-0.5\"\n :loader=\"acquisitionLoader\"\n size=\"sm\"\n @click=\"handleConfigAuthorize\">\n Authorize\n </ScalarButton>\n </div>\n </ScalarModal>\n</template>\n"],"mappings":""}
|
|
@@ -1,27 +1,40 @@
|
|
|
1
|
+
import DataTable_default from "../../../components/data-table/DataTable.vue.js";
|
|
1
2
|
import DataTableCell_default from "../../../components/data-table/DataTableCell.vue.js";
|
|
2
3
|
import DataTableRow_default from "../../../components/data-table/DataTableRow.vue.js";
|
|
4
|
+
import { getOauth2AcquisitionTarget } from "../helpers/security-scheme.js";
|
|
5
|
+
import { refreshOauth2Token } from "../helpers/oauth.js";
|
|
6
|
+
import { runOAuth2Authorize, storeOAuth2Tokens } from "../helpers/run-oauth2-authorize.js";
|
|
3
7
|
import RequestAuthDataTableInput_default from "./RequestAuthDataTableInput.vue.js";
|
|
4
8
|
import OAuth2_default from "./OAuth2.vue.js";
|
|
5
9
|
import OpenIDConnect_default from "./OpenIDConnect.vue.js";
|
|
6
10
|
import { Fragment, capitalize, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, openBlock, ref, renderList, toDisplayString, unref, withCtx } from "vue";
|
|
11
|
+
import { ScalarButton } from "@scalar/components/button";
|
|
12
|
+
import { ScalarIconGear } from "@scalar/icons";
|
|
13
|
+
import { ScalarModal, useModal } from "@scalar/components/modal";
|
|
14
|
+
import { ScalarIconButton } from "@scalar/components/icon-button";
|
|
15
|
+
import { getEnvironmentVariables, isEncryptionSchemeType, isSaslSchemeType } from "@scalar/workspace-store/request-example";
|
|
16
|
+
import { useToasts } from "@scalar/use-toasts";
|
|
7
17
|
import { getResolvedRef } from "@scalar/workspace-store/helpers/get-resolved-ref";
|
|
8
18
|
import { ScalarMarkdownSummary } from "@scalar/components/markdown";
|
|
19
|
+
import { useLoadingState } from "@scalar/components/loading";
|
|
9
20
|
import { getDocumentTypeLabel } from "@scalar/workspace-store/schemas/type-guards";
|
|
10
21
|
//#region src/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue?vue&type=script&setup=true&lang.ts
|
|
11
22
|
var _hoisted_1 = { class: "bg-b-1 min-w-0 flex-1 px-3 py-1.25" };
|
|
12
23
|
var _hoisted_2 = { class: "text-c-1 leading-5.5 font-medium" };
|
|
13
|
-
var _hoisted_3 = { class: "flex
|
|
14
|
-
var _hoisted_4 = { class: "flex h-8
|
|
15
|
-
var _hoisted_5 =
|
|
16
|
-
var _hoisted_6 =
|
|
17
|
-
var _hoisted_7 = {
|
|
18
|
-
|
|
24
|
+
var _hoisted_3 = { class: "flex h-8 items-center gap-2 border-t px-3" };
|
|
25
|
+
var _hoisted_4 = { class: "flex min-h-8 border-t text-base" };
|
|
26
|
+
var _hoisted_5 = { class: "flex h-8 max-w-full gap-2.5 overflow-x-auto px-3" };
|
|
27
|
+
var _hoisted_6 = ["onClick"];
|
|
28
|
+
var _hoisted_7 = { class: "relative z-10" };
|
|
29
|
+
var _hoisted_8 = {
|
|
30
|
+
key: 9,
|
|
19
31
|
class: "text-c-3 flex items-center justify-center border-t p-4 px-4 text-center text-xs text-balance"
|
|
20
32
|
};
|
|
21
|
-
var
|
|
22
|
-
key:
|
|
33
|
+
var _hoisted_9 = {
|
|
34
|
+
key: 10,
|
|
23
35
|
class: "text-c-3 flex items-center justify-center border-t p-4 px-4 text-center text-xs text-balance"
|
|
24
36
|
};
|
|
37
|
+
var _hoisted_10 = { class: "flex h-8 items-center justify-end gap-2 border-t" };
|
|
25
38
|
var RequestAuthTab_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
|
|
26
39
|
__name: "RequestAuthTab",
|
|
27
40
|
props: {
|
|
@@ -100,9 +113,20 @@ var RequestAuthTab_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
100
113
|
*/
|
|
101
114
|
const apiKeyHasName = (scheme) => scheme.in !== "user" && scheme.in !== "password";
|
|
102
115
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
|
|
116
|
+
* SASL-style AsyncAPI broker schemes (`userPassword`, `plain`, `scramSha256`, `scramSha512`):
|
|
117
|
+
* they all authenticate with a username + password pair, so they share one form.
|
|
118
|
+
*/
|
|
119
|
+
const isSaslScheme = (scheme) => isSaslSchemeType(scheme?.type);
|
|
120
|
+
/** AsyncAPI encryption broker schemes: a single key value. */
|
|
121
|
+
const isEncryptionScheme = (scheme) => isEncryptionSchemeType(scheme?.type);
|
|
122
|
+
/** AsyncAPI X509 broker scheme: a client certificate + private key pair (PEM). */
|
|
123
|
+
const isX509Scheme = (scheme) => scheme?.type === "X509";
|
|
124
|
+
/** AsyncAPI GSSAPI (Kerberos) broker scheme: the service name the client authenticates against. */
|
|
125
|
+
const isGssapiScheme = (scheme) => scheme?.type === "gssapi";
|
|
126
|
+
/**
|
|
127
|
+
* The scheme's type when it is one we do not render inputs for (a type outside both the OpenAPI
|
|
128
|
+
* and AsyncAPI security scheme unions). Read through a helper so the fallback template branch,
|
|
129
|
+
* where the scheme type is narrowed to `never` after the supported cases, can still surface the type.
|
|
106
130
|
*/
|
|
107
131
|
const getUnsupportedSchemeType = (scheme) => scheme?.type;
|
|
108
132
|
/**
|
|
@@ -126,6 +150,15 @@ var RequestAuthTab_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
126
150
|
},
|
|
127
151
|
name
|
|
128
152
|
});
|
|
153
|
+
/**
|
|
154
|
+
* AsyncAPI broker credentials (SASL, X509, encryption, GSSAPI) all persist through the same
|
|
155
|
+
* event; only the secret key and scheme type differ, so they share one handler. The caller passes
|
|
156
|
+
* a payload that already carries the narrowed scheme `type`.
|
|
157
|
+
*/
|
|
158
|
+
const handleBrokerSecretsUpdate = (payload, name) => __props.eventBus.emit("auth:update:security-scheme-secrets", {
|
|
159
|
+
payload,
|
|
160
|
+
name
|
|
161
|
+
});
|
|
129
162
|
const handleApiKeySecuritySchemeUpdate = (payload, name) => __props.eventBus.emit("auth:update:security-scheme", {
|
|
130
163
|
payload: {
|
|
131
164
|
type: "apiKey",
|
|
@@ -162,8 +195,72 @@ var RequestAuthTab_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
162
195
|
const baseClasses = "floating-bg text-c-3 relative cursor-pointer border-b border-transparent py-1 text-base font-medium";
|
|
163
196
|
return isFlowActive(flowKey, index) ? `${baseClasses} !text-c-1 !rounded-none border-b !border-current ${__props.isStatic ? "opacity-100" : ""}` : baseClasses;
|
|
164
197
|
};
|
|
198
|
+
/**
|
|
199
|
+
* OAuth2 token-acquisition target (an oauth2 scheme with an interactive grant) sourced from
|
|
200
|
+
* the merged schemes. When the active scheme is HTTP bearer, this powers the inline
|
|
201
|
+
* "Authorize via OAuth2" shortcut: the flow's bearer token is written onto the bearer scheme,
|
|
202
|
+
* so the panel never switches to oauth2.
|
|
203
|
+
*
|
|
204
|
+
* The shortcut is purely a convenience, so it is offered for any interactive oauth2 scheme —
|
|
205
|
+
* including one that is also independently selectable in the dropdown (e.g. Scalar Galaxy's
|
|
206
|
+
* `oAuth2`). Whether that oauth2 scheme is *hidden* from the dropdown is a separate decision made
|
|
207
|
+
* in the selector; here we only surface the shortcut.
|
|
208
|
+
*/
|
|
209
|
+
const oauth2Target = computed(() => getOauth2AcquisitionTarget(__props.securitySchemes));
|
|
210
|
+
/** Resolved oauth2 scheme object, for embedding its config form behind the gear. */
|
|
211
|
+
const oauth2Scheme = computed(() => oauth2Target.value ? getResolvedRef(__props.securitySchemes[oauth2Target.value.name]) : void 0);
|
|
212
|
+
const acquisitionLoader = useLoadingState();
|
|
213
|
+
const { toast } = useToasts();
|
|
214
|
+
const configModal = useModal();
|
|
215
|
+
/** Bearer scheme that opened the config modal, so its Authorize callback targets it. */
|
|
216
|
+
const configBearerName = ref();
|
|
217
|
+
/** Runs the OAuth2 flow and writes the resulting bearer token onto the bearer scheme. */
|
|
218
|
+
const handleAcquisitionAuthorize = async (bearerName) => {
|
|
219
|
+
const target = oauth2Target.value;
|
|
220
|
+
if (!target || acquisitionLoader.isLoading) return;
|
|
221
|
+
acquisitionLoader.start();
|
|
222
|
+
const [error] = await runOAuth2Authorize({
|
|
223
|
+
eventBus: __props.eventBus,
|
|
224
|
+
bearerSchemeName: bearerName,
|
|
225
|
+
oauth2Name: target.name,
|
|
226
|
+
flows: target.flows,
|
|
227
|
+
flowType: target.flowType,
|
|
228
|
+
scopes: target.scopes,
|
|
229
|
+
server: __props.server,
|
|
230
|
+
proxyUrl: __props.proxyUrl,
|
|
231
|
+
environment: __props.environment,
|
|
232
|
+
options: __props.options
|
|
233
|
+
});
|
|
234
|
+
await acquisitionLoader.clear();
|
|
235
|
+
if (error) toast(error?.message ?? "Failed to authorize", "error");
|
|
236
|
+
};
|
|
237
|
+
/** Refreshes the OAuth2 token and rewrites it onto the bearer scheme. */
|
|
238
|
+
const handleAcquisitionRefresh = async (bearerName) => {
|
|
239
|
+
const target = oauth2Target.value;
|
|
240
|
+
if (!target || target.flowType !== "authorizationCode" || acquisitionLoader.isLoading) return;
|
|
241
|
+
acquisitionLoader.start();
|
|
242
|
+
const [error, tokens] = await refreshOauth2Token(target.flows, target.flowType, __props.proxyUrl, __props.server, getEnvironmentVariables(__props.environment), __props.options?.customFetch);
|
|
243
|
+
await acquisitionLoader.clear();
|
|
244
|
+
if (tokens?.accessToken) storeOAuth2Tokens(__props.eventBus, {
|
|
245
|
+
bearerSchemeName: bearerName,
|
|
246
|
+
oauth2Name: target.name,
|
|
247
|
+
flowType: target.flowType,
|
|
248
|
+
tokens
|
|
249
|
+
});
|
|
250
|
+
else if (error) toast(error?.message ?? "Failed to refresh", "error");
|
|
251
|
+
};
|
|
252
|
+
const openAcquisitionConfig = (bearerName) => {
|
|
253
|
+
configBearerName.value = bearerName;
|
|
254
|
+
configModal.show();
|
|
255
|
+
};
|
|
256
|
+
/** Closes the config modal and runs Authorize against the bearer scheme that opened it. */
|
|
257
|
+
const handleConfigAuthorize = () => {
|
|
258
|
+
const bearerName = configBearerName.value;
|
|
259
|
+
configModal.hide();
|
|
260
|
+
if (bearerName) handleAcquisitionAuthorize(bearerName);
|
|
261
|
+
};
|
|
165
262
|
return (_ctx, _cache) => {
|
|
166
|
-
return openBlock(true), createElementBlock(Fragment, null, renderList(security.value, ({ scheme, name, scopes }) => {
|
|
263
|
+
return openBlock(), createElementBlock(Fragment, null, [(openBlock(true), createElementBlock(Fragment, null, renderList(security.value, ({ scheme, name, scopes }) => {
|
|
167
264
|
return openBlock(), createElementBlock(Fragment, { key: name }, [
|
|
168
265
|
hasMultipleSchemes.value && scheme ? (openBlock(), createBlock(unref(DataTableRow_default), { key: 0 }, {
|
|
169
266
|
default: withCtx(() => [createVNode(unref(DataTableCell_default), {
|
|
@@ -201,7 +298,7 @@ var RequestAuthTab_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
201
298
|
type: "password",
|
|
202
299
|
"onUpdate:modelValue": (v) => handleHttpSecretsUpdate({ "x-scalar-secret-token": v }, name)
|
|
203
300
|
}, {
|
|
204
|
-
default: withCtx(() => [..._cache[
|
|
301
|
+
default: withCtx(() => [..._cache[4] || (_cache[4] = [createTextVNode(" Bearer Token ", -1)])]),
|
|
205
302
|
_: 1
|
|
206
303
|
}, 8, [
|
|
207
304
|
"containerClass",
|
|
@@ -210,7 +307,45 @@ var RequestAuthTab_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
210
307
|
"onUpdate:modelValue"
|
|
211
308
|
])]),
|
|
212
309
|
_: 2
|
|
213
|
-
}, 1024)) : scheme
|
|
310
|
+
}, 1024)) : createCommentVNode("", true), scheme.scheme === "bearer" && oauth2Target.value ? (openBlock(), createBlock(unref(DataTableRow_default), { key: 1 }, {
|
|
311
|
+
default: withCtx(() => [createElementVNode("div", _hoisted_3, [
|
|
312
|
+
_cache[6] || (_cache[6] = createElementVNode("span", { class: "text-c-3 mr-auto text-xs" }, "Get a token", -1)),
|
|
313
|
+
createVNode(unref(ScalarButton), {
|
|
314
|
+
class: "p-0 px-2 py-0.5",
|
|
315
|
+
loader: unref(acquisitionLoader),
|
|
316
|
+
size: "sm",
|
|
317
|
+
type: "button",
|
|
318
|
+
variant: "outlined",
|
|
319
|
+
onClick: ($event) => handleAcquisitionAuthorize(name)
|
|
320
|
+
}, {
|
|
321
|
+
default: withCtx(() => [createTextVNode(" Authorize via " + toDisplayString(oauth2Target.value.name), 1)]),
|
|
322
|
+
_: 2
|
|
323
|
+
}, 1032, ["loader", "onClick"]),
|
|
324
|
+
scheme["x-scalar-secret-token"] && oauth2Target.value.flowType === "authorizationCode" ? (openBlock(), createBlock(unref(ScalarButton), {
|
|
325
|
+
key: 0,
|
|
326
|
+
class: "p-0 px-2 py-0.5",
|
|
327
|
+
disabled: unref(acquisitionLoader).isLoading,
|
|
328
|
+
size: "sm",
|
|
329
|
+
type: "button",
|
|
330
|
+
variant: "outlined",
|
|
331
|
+
onClick: ($event) => handleAcquisitionRefresh(name)
|
|
332
|
+
}, {
|
|
333
|
+
default: withCtx(() => [..._cache[5] || (_cache[5] = [createTextVNode(" Refresh ", -1)])]),
|
|
334
|
+
_: 1
|
|
335
|
+
}, 8, ["disabled", "onClick"])) : createCommentVNode("", true),
|
|
336
|
+
createVNode(unref(ScalarIconButton), {
|
|
337
|
+
icon: unref(ScalarIconGear),
|
|
338
|
+
label: `Configure ${oauth2Target.value.name}`,
|
|
339
|
+
size: "xs",
|
|
340
|
+
onClick: ($event) => openAcquisitionConfig(name)
|
|
341
|
+
}, null, 8, [
|
|
342
|
+
"icon",
|
|
343
|
+
"label",
|
|
344
|
+
"onClick"
|
|
345
|
+
])
|
|
346
|
+
])]),
|
|
347
|
+
_: 2
|
|
348
|
+
}, 1024)) : scheme?.scheme === "basic" ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [createVNode(unref(DataTableRow_default), null, {
|
|
214
349
|
default: withCtx(() => [createVNode(RequestAuthDataTableInput_default, {
|
|
215
350
|
class: "text-c-2",
|
|
216
351
|
environment: __props.environment,
|
|
@@ -219,7 +354,7 @@ var RequestAuthTab_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
219
354
|
required: "",
|
|
220
355
|
"onUpdate:modelValue": (v) => handleHttpSecretsUpdate({ "x-scalar-secret-username": v }, name)
|
|
221
356
|
}, {
|
|
222
|
-
default: withCtx(() => [..._cache[
|
|
357
|
+
default: withCtx(() => [..._cache[7] || (_cache[7] = [createTextVNode(" Username ", -1)])]),
|
|
223
358
|
_: 1
|
|
224
359
|
}, 8, [
|
|
225
360
|
"environment",
|
|
@@ -235,7 +370,7 @@ var RequestAuthTab_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
235
370
|
type: "password",
|
|
236
371
|
"onUpdate:modelValue": (v) => handleHttpSecretsUpdate({ "x-scalar-secret-password": v }, name)
|
|
237
372
|
}, {
|
|
238
|
-
default: withCtx(() => [..._cache[
|
|
373
|
+
default: withCtx(() => [..._cache[8] || (_cache[8] = [createTextVNode(" Password ", -1)])]),
|
|
239
374
|
_: 1
|
|
240
375
|
}, 8, [
|
|
241
376
|
"environment",
|
|
@@ -251,7 +386,7 @@ var RequestAuthTab_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
251
386
|
placeholder: "api-key",
|
|
252
387
|
"onUpdate:modelValue": (v) => handleApiKeySecuritySchemeUpdate({ name: v }, name)
|
|
253
388
|
}, {
|
|
254
|
-
default: withCtx(() => [..._cache[
|
|
389
|
+
default: withCtx(() => [..._cache[9] || (_cache[9] = [createTextVNode(" Name ", -1)])]),
|
|
255
390
|
_: 1
|
|
256
391
|
}, 8, [
|
|
257
392
|
"containerClass",
|
|
@@ -269,7 +404,7 @@ var RequestAuthTab_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
269
404
|
type: "password",
|
|
270
405
|
"onUpdate:modelValue": (v) => handleApiKeySecretsUpdate({ "x-scalar-secret-token": v }, name)
|
|
271
406
|
}, {
|
|
272
|
-
default: withCtx(() => [..._cache[
|
|
407
|
+
default: withCtx(() => [..._cache[10] || (_cache[10] = [createTextVNode(" Value ", -1)])]),
|
|
273
408
|
_: 1
|
|
274
409
|
}, 8, [
|
|
275
410
|
"containerClass",
|
|
@@ -297,13 +432,13 @@ var RequestAuthTab_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
297
432
|
"scheme"
|
|
298
433
|
])) : createCommentVNode("", true),
|
|
299
434
|
Object.keys(scheme.flows ?? {}).length > 1 ? (openBlock(), createBlock(unref(DataTableRow_default), { key: 1 }, {
|
|
300
|
-
default: withCtx(() => [createElementVNode("div",
|
|
435
|
+
default: withCtx(() => [createElementVNode("div", _hoisted_4, [createElementVNode("div", _hoisted_5, [(openBlock(true), createElementBlock(Fragment, null, renderList(scheme.flows, (_, key, ind) => {
|
|
301
436
|
return openBlock(), createElementBlock("button", {
|
|
302
437
|
key,
|
|
303
438
|
class: normalizeClass(getFlowTabClasses(key, ind)),
|
|
304
439
|
type: "button",
|
|
305
440
|
onClick: ($event) => setActiveFlow(key)
|
|
306
|
-
}, [createElementVNode("span",
|
|
441
|
+
}, [createElementVNode("span", _hoisted_7, toDisplayString(key), 1)], 10, _hoisted_6);
|
|
307
442
|
}), 128))])])]),
|
|
308
443
|
_: 2
|
|
309
444
|
}, 1024)) : createCommentVNode("", true),
|
|
@@ -339,13 +474,191 @@ var RequestAuthTab_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
339
474
|
"onUpsert:scope"
|
|
340
475
|
])) : createCommentVNode("", true)], 64);
|
|
341
476
|
}), 128))
|
|
342
|
-
], 64)) :
|
|
343
|
-
|
|
477
|
+
], 64)) : isSaslScheme(scheme) ? (openBlock(), createElementBlock(Fragment, { key: 5 }, [createVNode(unref(DataTableRow_default), null, {
|
|
478
|
+
default: withCtx(() => [createVNode(RequestAuthDataTableInput_default, {
|
|
479
|
+
class: "text-c-2",
|
|
480
|
+
containerClass: getStaticBorderClass(),
|
|
481
|
+
environment: __props.environment,
|
|
482
|
+
modelValue: scheme["x-scalar-secret-username"],
|
|
483
|
+
placeholder: "janedoe",
|
|
484
|
+
required: "",
|
|
485
|
+
"onUpdate:modelValue": (v) => handleBrokerSecretsUpdate({
|
|
486
|
+
"type": scheme.type,
|
|
487
|
+
"x-scalar-secret-username": v
|
|
488
|
+
}, name)
|
|
489
|
+
}, {
|
|
490
|
+
default: withCtx(() => [..._cache[11] || (_cache[11] = [createTextVNode(" Username ", -1)])]),
|
|
491
|
+
_: 1
|
|
492
|
+
}, 8, [
|
|
493
|
+
"containerClass",
|
|
494
|
+
"environment",
|
|
495
|
+
"modelValue",
|
|
496
|
+
"onUpdate:modelValue"
|
|
497
|
+
])]),
|
|
498
|
+
_: 2
|
|
499
|
+
}, 1024), createVNode(unref(DataTableRow_default), null, {
|
|
500
|
+
default: withCtx(() => [createVNode(RequestAuthDataTableInput_default, {
|
|
501
|
+
environment: __props.environment,
|
|
502
|
+
modelValue: scheme["x-scalar-secret-password"],
|
|
503
|
+
placeholder: "********",
|
|
504
|
+
type: "password",
|
|
505
|
+
"onUpdate:modelValue": (v) => handleBrokerSecretsUpdate({
|
|
506
|
+
"type": scheme.type,
|
|
507
|
+
"x-scalar-secret-password": v
|
|
508
|
+
}, name)
|
|
509
|
+
}, {
|
|
510
|
+
default: withCtx(() => [..._cache[12] || (_cache[12] = [createTextVNode(" Password ", -1)])]),
|
|
511
|
+
_: 1
|
|
512
|
+
}, 8, [
|
|
513
|
+
"environment",
|
|
514
|
+
"modelValue",
|
|
515
|
+
"onUpdate:modelValue"
|
|
516
|
+
])]),
|
|
517
|
+
_: 2
|
|
518
|
+
}, 1024)], 64)) : isX509Scheme(scheme) ? (openBlock(), createElementBlock(Fragment, { key: 6 }, [createVNode(unref(DataTableRow_default), null, {
|
|
519
|
+
default: withCtx(() => [createVNode(RequestAuthDataTableInput_default, {
|
|
520
|
+
containerClass: getStaticBorderClass(),
|
|
521
|
+
environment: __props.environment,
|
|
522
|
+
modelValue: scheme["x-scalar-secret-client-certificate"],
|
|
523
|
+
placeholder: "-----BEGIN CERTIFICATE-----",
|
|
524
|
+
type: "password",
|
|
525
|
+
"onUpdate:modelValue": (v) => handleBrokerSecretsUpdate({
|
|
526
|
+
"type": scheme.type,
|
|
527
|
+
"x-scalar-secret-client-certificate": v
|
|
528
|
+
}, name)
|
|
529
|
+
}, {
|
|
530
|
+
default: withCtx(() => [..._cache[13] || (_cache[13] = [createTextVNode(" Client Certificate ", -1)])]),
|
|
531
|
+
_: 1
|
|
532
|
+
}, 8, [
|
|
533
|
+
"containerClass",
|
|
534
|
+
"environment",
|
|
535
|
+
"modelValue",
|
|
536
|
+
"onUpdate:modelValue"
|
|
537
|
+
])]),
|
|
538
|
+
_: 2
|
|
539
|
+
}, 1024), createVNode(unref(DataTableRow_default), null, {
|
|
540
|
+
default: withCtx(() => [createVNode(RequestAuthDataTableInput_default, {
|
|
541
|
+
environment: __props.environment,
|
|
542
|
+
modelValue: scheme["x-scalar-secret-private-key"],
|
|
543
|
+
placeholder: "-----BEGIN PRIVATE KEY-----",
|
|
544
|
+
type: "password",
|
|
545
|
+
"onUpdate:modelValue": (v) => handleBrokerSecretsUpdate({
|
|
546
|
+
"type": scheme.type,
|
|
547
|
+
"x-scalar-secret-private-key": v
|
|
548
|
+
}, name)
|
|
549
|
+
}, {
|
|
550
|
+
default: withCtx(() => [..._cache[14] || (_cache[14] = [createTextVNode(" Private Key ", -1)])]),
|
|
551
|
+
_: 1
|
|
552
|
+
}, 8, [
|
|
553
|
+
"environment",
|
|
554
|
+
"modelValue",
|
|
555
|
+
"onUpdate:modelValue"
|
|
556
|
+
])]),
|
|
557
|
+
_: 2
|
|
558
|
+
}, 1024)], 64)) : isEncryptionScheme(scheme) ? (openBlock(), createBlock(unref(DataTableRow_default), { key: 7 }, {
|
|
559
|
+
default: withCtx(() => [createVNode(RequestAuthDataTableInput_default, {
|
|
560
|
+
containerClass: getStaticBorderClass(),
|
|
561
|
+
environment: __props.environment,
|
|
562
|
+
modelValue: scheme["x-scalar-secret-token"],
|
|
563
|
+
placeholder: "********",
|
|
564
|
+
type: "password",
|
|
565
|
+
"onUpdate:modelValue": (v) => handleBrokerSecretsUpdate({
|
|
566
|
+
"type": scheme.type,
|
|
567
|
+
"x-scalar-secret-token": v
|
|
568
|
+
}, name)
|
|
569
|
+
}, {
|
|
570
|
+
default: withCtx(() => [..._cache[15] || (_cache[15] = [createTextVNode(" Key ", -1)])]),
|
|
571
|
+
_: 1
|
|
572
|
+
}, 8, [
|
|
573
|
+
"containerClass",
|
|
574
|
+
"environment",
|
|
575
|
+
"modelValue",
|
|
576
|
+
"onUpdate:modelValue"
|
|
577
|
+
])]),
|
|
578
|
+
_: 2
|
|
579
|
+
}, 1024)) : isGssapiScheme(scheme) ? (openBlock(), createBlock(unref(DataTableRow_default), { key: 8 }, {
|
|
580
|
+
default: withCtx(() => [createVNode(RequestAuthDataTableInput_default, {
|
|
581
|
+
containerClass: getStaticBorderClass(),
|
|
582
|
+
environment: __props.environment,
|
|
583
|
+
modelValue: scheme["x-scalar-secret-service-name"],
|
|
584
|
+
placeholder: "kafka",
|
|
585
|
+
"onUpdate:modelValue": (v) => handleBrokerSecretsUpdate({
|
|
586
|
+
"type": scheme.type,
|
|
587
|
+
"x-scalar-secret-service-name": v
|
|
588
|
+
}, name)
|
|
589
|
+
}, {
|
|
590
|
+
default: withCtx(() => [..._cache[16] || (_cache[16] = [createTextVNode(" Service Name ", -1)])]),
|
|
591
|
+
_: 1
|
|
592
|
+
}, 8, [
|
|
593
|
+
"containerClass",
|
|
594
|
+
"environment",
|
|
595
|
+
"modelValue",
|
|
596
|
+
"onUpdate:modelValue"
|
|
597
|
+
])]),
|
|
598
|
+
_: 2
|
|
599
|
+
}, 1024)) : getUnsupportedSchemeType(scheme) ? (openBlock(), createElementBlock("div", _hoisted_8, [
|
|
600
|
+
_cache[17] || (_cache[17] = createTextVNode(" The ", -1)),
|
|
344
601
|
createElementVNode("code", null, toDisplayString(getUnsupportedSchemeType(scheme)), 1),
|
|
345
|
-
_cache[
|
|
346
|
-
])) : (openBlock(), createElementBlock("div",
|
|
602
|
+
_cache[18] || (_cache[18] = createTextVNode(" security scheme type is not supported yet. ", -1))
|
|
603
|
+
])) : (openBlock(), createElementBlock("div", _hoisted_9, " The security scheme is missing a type, please double check your " + toDisplayString(documentTypeLabel.value) + " document or Authentication Configuration ", 1))
|
|
347
604
|
], 64);
|
|
348
|
-
}), 128)
|
|
605
|
+
}), 128)), oauth2Target.value && oauth2Scheme.value ? (openBlock(), createBlock(unref(ScalarModal), {
|
|
606
|
+
key: 0,
|
|
607
|
+
state: unref(configModal),
|
|
608
|
+
size: "sm",
|
|
609
|
+
title: `Configure ${oauth2Target.value.name}`
|
|
610
|
+
}, {
|
|
611
|
+
default: withCtx(() => [createVNode(unref(DataTable_default), {
|
|
612
|
+
columns: [""],
|
|
613
|
+
presentational: ""
|
|
614
|
+
}, {
|
|
615
|
+
default: withCtx(() => [createVNode(OAuth2_default, {
|
|
616
|
+
hideActions: "",
|
|
617
|
+
environment: __props.environment,
|
|
618
|
+
eventBus: __props.eventBus,
|
|
619
|
+
flows: oauth2Target.value.flows,
|
|
620
|
+
name: oauth2Target.value.name,
|
|
621
|
+
options: __props.options,
|
|
622
|
+
proxyUrl: __props.proxyUrl,
|
|
623
|
+
scheme: oauth2Scheme.value,
|
|
624
|
+
selectedScopes: oauth2Target.value.scopes,
|
|
625
|
+
server: __props.server,
|
|
626
|
+
type: oauth2Target.value.flowType,
|
|
627
|
+
"onDelete:scope": _cache[0] || (_cache[0] = (event) => handleScopeDelete(oauth2Target.value.name, event)),
|
|
628
|
+
"onUpdate:selectedScopes": _cache[1] || (_cache[1] = (event) => handleScopesUpdate(oauth2Target.value.name, event)),
|
|
629
|
+
"onUpsert:scope": _cache[2] || (_cache[2] = (event) => handleScopeUpsert(oauth2Target.value.name, event))
|
|
630
|
+
}, null, 8, [
|
|
631
|
+
"environment",
|
|
632
|
+
"eventBus",
|
|
633
|
+
"flows",
|
|
634
|
+
"name",
|
|
635
|
+
"options",
|
|
636
|
+
"proxyUrl",
|
|
637
|
+
"scheme",
|
|
638
|
+
"selectedScopes",
|
|
639
|
+
"server",
|
|
640
|
+
"type"
|
|
641
|
+
])]),
|
|
642
|
+
_: 1
|
|
643
|
+
}), createElementVNode("div", _hoisted_10, [createVNode(unref(ScalarButton), {
|
|
644
|
+
class: "p-0 px-2 py-0.5",
|
|
645
|
+
size: "sm",
|
|
646
|
+
variant: "outlined",
|
|
647
|
+
onClick: _cache[3] || (_cache[3] = ($event) => unref(configModal).hide())
|
|
648
|
+
}, {
|
|
649
|
+
default: withCtx(() => [..._cache[19] || (_cache[19] = [createTextVNode(" Cancel ", -1)])]),
|
|
650
|
+
_: 1
|
|
651
|
+
}), createVNode(unref(ScalarButton), {
|
|
652
|
+
class: "p-0 px-2 py-0.5",
|
|
653
|
+
loader: unref(acquisitionLoader),
|
|
654
|
+
size: "sm",
|
|
655
|
+
onClick: handleConfigAuthorize
|
|
656
|
+
}, {
|
|
657
|
+
default: withCtx(() => [..._cache[20] || (_cache[20] = [createTextVNode(" Authorize ", -1)])]),
|
|
658
|
+
_: 1
|
|
659
|
+
}, 8, ["loader"])])]),
|
|
660
|
+
_: 1
|
|
661
|
+
}, 8, ["state", "title"])) : createCommentVNode("", true)], 64);
|
|
349
662
|
};
|
|
350
663
|
}
|
|
351
664
|
});
|