From 5480e1ce4e77b64b5ae015582fa359218c452e01 Mon Sep 17 00:00:00 2001 From: Ellyx Christian Date: Fri, 16 Sep 2022 17:37:31 +0800 Subject: [PATCH] send credential when bundling $ref based on this PR https://github.com/stoplightio/elements/pull/2006 --- .../src/hooks/useBundleRefsIntoDocument.ts | 15 +++++++++++---- packages/elements/src/containers/API.tsx | 10 +++++++++- .../elements/src/web-components/components.ts | 1 + 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/packages/elements-core/src/hooks/useBundleRefsIntoDocument.ts b/packages/elements-core/src/hooks/useBundleRefsIntoDocument.ts index 31cb06c24..0aee0f95f 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 = { + continueOnError: true, + resolve: { + http: <$RefParser.HTTPResolverOptions>{ withCredentials }, + }, + }; if (!baseUrl) { return $RefParser.bundle(data, commonBundleOptions); } else { 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' }, });