From 2eead18ee0592a33b42e8f86ac60358b370b2c39 Mon Sep 17 00:00:00 2001 From: Daniel Patterson Date: Fri, 28 Jan 2022 08:53:13 -0800 Subject: [PATCH] Add parameter to configure CORS withCredentials handling when resolving refs in HTTP served schemas. --- .../src/hooks/useBundleRefsIntoDocument.ts | 15 +++++++++++---- packages/elements-dev-portal/src/version.ts | 2 +- packages/elements/src/containers/API.tsx | 10 +++++++++- .../elements/src/web-components/components.ts | 1 + 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/packages/elements-core/src/hooks/useBundleRefsIntoDocument.ts b/packages/elements-core/src/hooks/useBundleRefsIntoDocument.ts index 31cb06c24..ecce473f9 100644 --- a/packages/elements-core/src/hooks/useBundleRefsIntoDocument.ts +++ b/packages/elements-core/src/hooks/useBundleRefsIntoDocument.ts @@ -9,6 +9,7 @@ import * as React from 'react'; interface Options { baseUrl?: string; + withCredentials?: boolean; } /** @@ -18,6 +19,7 @@ export function useBundleRefsIntoDocument(document: unknown, options?: Options) const [bundledData, setBundledData] = React.useState(document); const baseUrl = options?.baseUrl; + const withCredentials = options?.withCredentials; React.useEffect(() => { if (!isObject(document)) { @@ -26,7 +28,7 @@ export function useBundleRefsIntoDocument(document: unknown, options?: Options) } let isMounted = true; - doBundle(document, baseUrl) + doBundle(document, baseUrl, withCredentials) .then(res => { if (isMounted) { setBundledData({ ...res }); // this hmm....library mutates document so a shallow copy is required to force a rerender in all cases @@ -45,13 +47,18 @@ export function useBundleRefsIntoDocument(document: unknown, options?: Options) return () => { isMounted = false; }; - }, [document, baseUrl]); + }, [document, baseUrl, withCredentials]); return bundledData; } -const commonBundleOptions = { continueOnError: true }; -const doBundle = (data: object, baseUrl?: string) => { +const doBundle = (data: object, baseUrl?: string, withCredentials?: boolean) => { + const commonBundleOptions: $RefParser.Options = { + continueOnError: true, + resolve: { + http: <$RefParser.HTTPResolverOptions>{ withCredentials }, + }, + }; if (!baseUrl) { return $RefParser.bundle(data, commonBundleOptions); } else { diff --git a/packages/elements-dev-portal/src/version.ts b/packages/elements-dev-portal/src/version.ts index 0688119da..0c3ab3700 100644 --- a/packages/elements-dev-portal/src/version.ts +++ b/packages/elements-dev-portal/src/version.ts @@ -1,2 +1,2 @@ // auto-updated during build -export const appVersion = '1.6.7'; +export const appVersion = '1.6.9'; diff --git a/packages/elements/src/containers/API.tsx b/packages/elements/src/containers/API.tsx index 341be5902..6e7eb0d0b 100644 --- a/packages/elements/src/containers/API.tsx +++ b/packages/elements/src/containers/API.tsx @@ -88,6 +88,13 @@ export interface CommonAPIProps extends RoutingProps { * @default false */ tryItCorsProxy?: string; + + /** + * Whether to include CORS credentials (cookies, authorization headers, TLS client certificates) + * in remote ref requests + * @default: false + */ + withCredentials?: boolean; } const propsAreWithDocument = (props: APIProps): props is APIPropsWithDocument => { @@ -105,6 +112,7 @@ export const APIImpl: React.FC = props => { hideExport, tryItCredentialsPolicy, tryItCorsProxy, + withCredentials, } = props; const apiDescriptionDocument = propsAreWithDocument(props) ? props.apiDescriptionDocument : undefined; @@ -124,7 +132,7 @@ export const APIImpl: React.FC = props => { const document = apiDescriptionDocument || fetchedDocument || ''; const parsedDocument = useParsedValue(document); - const bundledDocument = useBundleRefsIntoDocument(parsedDocument, { baseUrl: apiDescriptionUrl }); + const bundledDocument = useBundleRefsIntoDocument(parsedDocument, { baseUrl: apiDescriptionUrl, withCredentials }); const serviceNode = React.useMemo(() => transformOasToServiceNode(bundledDocument), [bundledDocument]); const exportProps = useExportDocumentProps({ originalDocument: document, bundledDocument }); diff --git a/packages/elements/src/web-components/components.ts b/packages/elements/src/web-components/components.ts index 0244b8943..61a590c71 100644 --- a/packages/elements/src/web-components/components.ts +++ b/packages/elements/src/web-components/components.ts @@ -16,4 +16,5 @@ export const ApiElement = createElementClass(API, { logo: { type: 'string' }, tryItCredentialsPolicy: { type: 'string' }, tryItCorsProxy: { type: 'string' }, + withCredentials: { type: 'boolean' }, });