fix(oauth-provider): correct consent and continue OpenAPI response schemas (#10881)

Co-authored-by: Taesu <166604494+bytaesu@users.noreply.github.com>
Co-authored-by: Taesu <bytaesu@gmail.com>
This commit is contained in:
Sahil Jagtap
2026-10-15 15:39:50 +00:00
committed by GitHub
co-authored by Taesu Taesu
parent 9ecd71fd6c
commit 37debaa8a1
3 changed files with 68 additions and 11 deletions
@@ -0,0 +1,5 @@
---
"@better-auth/oauth-provider": patch
---
Corrected the OpenAPI response schemas for `/oauth2/consent` and `/oauth2/continue` to describe `{ redirect: true, url: string }`, so generated clients no longer expect a nonexistent `redirect_uri` field. Runtime responses are unchanged.
+40
View File
@@ -5,6 +5,7 @@ import type { GenericOAuthConfig } from "better-auth/plugins/generic-oauth";
import { genericOAuth } from "better-auth/plugins/generic-oauth";
import { jwt } from "better-auth/plugins/jwt";
import { multiSession } from "better-auth/plugins/multi-session";
import { openAPI } from "better-auth/plugins/open-api";
import type { Organization } from "better-auth/plugins/organization";
import { organization } from "better-auth/plugins/organization";
import { getTestInstance } from "better-auth/test";
@@ -204,6 +205,45 @@ describe("oauth - init", () => {
});
});
/**
* @see https://github.com/better-auth/better-auth/issues/10880
*/
describe("oauth - OpenAPI response schemas", () => {
it.for(["/oauth2/consent", "/oauth2/continue"])(
"documents the redirect response for POST %s",
async (path, { expect }) => {
const { auth } = await getTestInstance(
{
plugins: [
jwt(),
oauthProvider({
loginPage: "/login",
consentPage: "/consent",
}),
openAPI(),
],
},
{ disableTestUser: true },
);
const document = await auth.api.generateOpenAPISchema();
const schema =
document.paths[path]?.post?.responses?.["200"]?.content?.[
"application/json"
]?.schema;
expect(schema).toMatchObject({
type: "object",
properties: {
redirect: { type: "boolean", enum: [true] },
url: { type: "string", format: "uri-reference" },
},
required: expect.arrayContaining(["redirect", "url"]),
});
expect(schema).not.toHaveProperty("properties.redirect_uri");
},
);
});
describe("oauth", async () => {
const port = 3001;
const authServerBaseUrl = `http://localhost:${port}`;
+23 -11
View File
@@ -824,14 +824,20 @@ export const oauthProvider = <O extends OAuthOptions<Scope[]>>(options: O) => {
schema: {
type: "object",
properties: {
redirect_uri: {
type: "string",
format: "uri",
redirect: {
type: "boolean",
description:
"The URI to redirect to, either with an authorization code or an error",
"Always true. Indicates the caller should redirect to `url`.",
enum: [true],
},
url: {
type: "string",
format: "uri-reference",
description:
"The absolute or relative URI to redirect to next.",
},
},
required: ["redirect_uri"],
required: ["redirect", "url"],
},
},
},
@@ -870,20 +876,26 @@ export const oauthProvider = <O extends OAuthOptions<Scope[]>>(options: O) => {
description: "Continues OAuth2 authorization flow",
responses: {
"200": {
description: "Consent processed successfully",
description: "Authorization flow continued successfully",
content: {
"application/json": {
schema: {
type: "object",
properties: {
redirect_uri: {
type: "string",
format: "uri",
redirect: {
type: "boolean",
description:
"The URI to redirect to, either with an authorization code or an error",
"Always true. Indicates the caller should redirect to `url`.",
enum: [true],
},
url: {
type: "string",
format: "uri-reference",
description:
"The absolute or relative URI to redirect to next.",
},
},
required: ["redirect_uri"],
required: ["redirect", "url"],
},
},
},