mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-25 04:20:02 +00:00
OpenAPI: Improve auth handling
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-openapi': patch
|
||||
---
|
||||
|
||||
Improve auth handling
|
||||
@@ -185,7 +185,7 @@ export default function Client({
|
||||
if (authorization && value.authorization) {
|
||||
authInfo.saveInfo(value.authorization);
|
||||
|
||||
writeAuthHeader(
|
||||
writeAuthInfo(
|
||||
authorization,
|
||||
value.authorization,
|
||||
value.header,
|
||||
@@ -264,35 +264,67 @@ function FormBody({
|
||||
return paramTypes.map((param) => parameters.filter((v) => v.in === param));
|
||||
}, [parameters]);
|
||||
|
||||
function renderAuth() {
|
||||
if (!authorization) return null;
|
||||
const schema: RequestSchema =
|
||||
authorization.type === 'http' && authorization.scheme === 'basic'
|
||||
? {
|
||||
type: 'object',
|
||||
required: ['username', 'password'],
|
||||
properties: {
|
||||
username: {
|
||||
type: 'string',
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
},
|
||||
const auth = useMemo(():
|
||||
| {
|
||||
in: string;
|
||||
field: RequestSchema;
|
||||
}
|
||||
| undefined => {
|
||||
if (!authorization) return;
|
||||
|
||||
if (authorization.type === 'http' && authorization.scheme === 'basic') {
|
||||
return {
|
||||
in: 'header',
|
||||
field: {
|
||||
type: 'object',
|
||||
required: ['username', 'password'],
|
||||
description: authorization.description,
|
||||
properties: {
|
||||
username: {
|
||||
type: 'string',
|
||||
},
|
||||
}
|
||||
: {
|
||||
type: 'string',
|
||||
description: 'The Authorization access token',
|
||||
};
|
||||
password: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
} else if (
|
||||
authorization.type === 'http' ||
|
||||
authorization.type === 'oauth2'
|
||||
) {
|
||||
return {
|
||||
in: 'header',
|
||||
field: {
|
||||
type: 'string',
|
||||
description:
|
||||
authorization.description ?? `The Authorization access token.`,
|
||||
},
|
||||
};
|
||||
} else if (authorization.type === 'apiKey') {
|
||||
return {
|
||||
in: authorization.in,
|
||||
field: {
|
||||
type: 'string',
|
||||
description: authorization.description ?? 'The API key.',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: handle OpenID connect
|
||||
}, [authorization]);
|
||||
|
||||
function renderAuth() {
|
||||
if (!auth) return null;
|
||||
|
||||
if (fields?.auth)
|
||||
return renderCustomField('authorization', schema, fields.auth);
|
||||
return renderCustomField('authorization', auth.field, fields.auth);
|
||||
|
||||
return (
|
||||
<FieldSet
|
||||
fieldName="authorization"
|
||||
name="Authorization"
|
||||
field={schema}
|
||||
field={auth.field}
|
||||
isRequired
|
||||
/>
|
||||
);
|
||||
@@ -303,12 +335,11 @@ function FormBody({
|
||||
{params.map((param, i) => {
|
||||
const name = paramNames[i];
|
||||
const type = paramTypes[i];
|
||||
if (type !== 'header' && param.length === 0) return;
|
||||
if (type === 'header' && !authorization && param.length === 0) return;
|
||||
if ((!auth || type !== auth.in) && param.length === 0) return;
|
||||
|
||||
return (
|
||||
<CollapsiblePanel key={name} title={name}>
|
||||
{type === 'header' ? renderAuth() : null}
|
||||
{auth && type === auth.in ? renderAuth() : null}
|
||||
{param.map((field) => {
|
||||
const fieldName = `${type}.${field.name}` as const;
|
||||
|
||||
@@ -563,7 +594,7 @@ function CollapsiblePanel({
|
||||
);
|
||||
}
|
||||
|
||||
function writeAuthHeader(
|
||||
function writeAuthInfo(
|
||||
authorization: Security,
|
||||
input: FormValues['authorization'],
|
||||
header: Record<string, unknown>,
|
||||
|
||||
@@ -35,24 +35,6 @@ export function createBrowserFetcher(
|
||||
? new URL(options.proxyUrl, window.location.origin)
|
||||
: null;
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
for (const key in options.cookie) {
|
||||
const value = options.cookie[key];
|
||||
if (!value) continue;
|
||||
|
||||
document.cookie = [
|
||||
`${key}=${value}`,
|
||||
'HttpOnly',
|
||||
proxyUrl &&
|
||||
proxyUrl.origin !== window.location.origin &&
|
||||
`domain=${proxyUrl.host}`,
|
||||
'path=/',
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(';');
|
||||
}
|
||||
}
|
||||
|
||||
let url = getPathnameFromInput(route, options.path, options.query);
|
||||
|
||||
if (proxyUrl) {
|
||||
@@ -73,6 +55,33 @@ export function createBrowserFetcher(
|
||||
body = await adapter.encode(options);
|
||||
}
|
||||
|
||||
// cookies
|
||||
for (const key in options.cookie) {
|
||||
const value = options.cookie[key];
|
||||
if (!value) continue;
|
||||
|
||||
const cookie = {
|
||||
[key]: value,
|
||||
domain:
|
||||
proxyUrl && proxyUrl.origin !== window.location.origin
|
||||
? `domain=${proxyUrl.host}`
|
||||
: undefined,
|
||||
path: '/',
|
||||
'max-age': 30,
|
||||
};
|
||||
|
||||
let str = '';
|
||||
for (const [key, value] of Object.entries(cookie)) {
|
||||
if (value) {
|
||||
if (str.length > 0) str += '; ';
|
||||
|
||||
str += `${key}=${value}`;
|
||||
}
|
||||
}
|
||||
|
||||
document.cookie = str;
|
||||
}
|
||||
|
||||
return fetch(url, {
|
||||
method: options.method,
|
||||
cache: 'no-cache',
|
||||
|
||||
@@ -135,7 +135,7 @@ function getAuthorizationField(
|
||||
|
||||
if (!item) {
|
||||
console.warn(
|
||||
`Cannot find suitable security scheme for API Playground from ${JSON.stringify(security, null, 2)}. Only schemes with one requirement are allowed.`,
|
||||
`Cannot find suitable security scheme for API Playground from ${JSON.stringify(security, null, 2)}. Only schemes with one requirement are allowed at the moment.`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user