mirror of
https://github.com/better-auth/better-auth.git
synced 2026-05-22 14:21:55 -05:00
fix(oauth-provider): improve allowed paths for oauth_query for client plugin (#8320)
This commit is contained in:
@@ -33,24 +33,14 @@ export const oauthProviderClient = () => {
|
||||
: safeJSONParse<Record<string, unknown>>(ctx.body ?? "{}")
|
||||
: ctx.body;
|
||||
if (body?.oauth_query) return;
|
||||
const pathname =
|
||||
typeof ctx.url === "string"
|
||||
? new URL(ctx.url).pathname
|
||||
: ctx.url.pathname;
|
||||
// Should only need to run for /sign-in/email, /sign-in/social, /sign-in/oauth2, /oauth2/consent, /oauth2/continue
|
||||
if (
|
||||
pathname.endsWith("/sign-in/email") ||
|
||||
pathname.endsWith("/sign-in/social") ||
|
||||
pathname.endsWith("/sign-in/oauth2") ||
|
||||
pathname.endsWith("/oauth2/consent") ||
|
||||
pathname.endsWith("/oauth2/continue")
|
||||
typeof window !== "undefined" &&
|
||||
window?.location?.search &&
|
||||
!(ctx.method === "GET" || ctx.method === "DELETE")
|
||||
) {
|
||||
ctx.body = JSON.stringify({
|
||||
...body,
|
||||
oauth_query:
|
||||
typeof window !== "undefined"
|
||||
? parseSignedQuery(window?.location?.search)
|
||||
: undefined,
|
||||
oauth_query: parseSignedQuery(window.location.search),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -447,6 +447,7 @@ describe("oauth - prompt", async () => {
|
||||
const scopes = ["openid", "profile", "email", "offline_access", "read:posts"];
|
||||
let enableSelectAccount = false;
|
||||
let enablePostLogin = false;
|
||||
let selectedPostLogin = false;
|
||||
let isUserRegistered = true;
|
||||
const {
|
||||
auth: authorizationServer,
|
||||
@@ -481,10 +482,12 @@ describe("oauth - prompt", async () => {
|
||||
page: "/select-organization",
|
||||
shouldRedirect({ session }) {
|
||||
if (!enablePostLogin) return false;
|
||||
if (selectedPostLogin) return false;
|
||||
return !session?.activeOrganizationId;
|
||||
},
|
||||
consentReferenceId({ session }) {
|
||||
if (!enablePostLogin) return undefined;
|
||||
if (selectedPostLogin) return undefined;
|
||||
const activeOrganizationId = (session?.activeOrganizationId ??
|
||||
undefined) as string | undefined;
|
||||
if (!activeOrganizationId)
|
||||
@@ -1426,6 +1429,84 @@ describe("oauth - prompt", async () => {
|
||||
enableSelectAccount = false;
|
||||
});
|
||||
|
||||
it("shall allow user to post login via continue", async ({
|
||||
onTestFinished,
|
||||
}) => {
|
||||
if (!oauthClient?.client_id || !oauthClient?.client_secret) {
|
||||
throw Error("beforeAll not run properly");
|
||||
}
|
||||
enablePostLogin = true;
|
||||
const { customFetchImpl: customFetchImplRP, cookieSetter } =
|
||||
await createTestInstance();
|
||||
const client = createAuthClient({
|
||||
plugins: [genericOAuthClient(), organization()],
|
||||
baseURL: rpBaseUrl,
|
||||
fetchOptions: {
|
||||
customFetchImpl: customFetchImplRP,
|
||||
},
|
||||
});
|
||||
|
||||
// Generate authorize url
|
||||
const oauthHeaders = new Headers();
|
||||
const data = await client.signIn.oauth2(
|
||||
{
|
||||
providerId,
|
||||
callbackURL: "/success",
|
||||
},
|
||||
{
|
||||
headers,
|
||||
throw: true,
|
||||
onSuccess: cookieSetter(oauthHeaders),
|
||||
},
|
||||
);
|
||||
expect(data.url).toContain(
|
||||
`${authServerBaseUrl}/api/auth/oauth2/authorize`,
|
||||
);
|
||||
expect(data.url).toContain(`client_id=${oauthClient.client_id}`);
|
||||
|
||||
// Check for redirection to /select-organization
|
||||
let selectOrgRedirectUri = "";
|
||||
await serverClient.$fetch(data.url, {
|
||||
method: "GET",
|
||||
headers,
|
||||
onError(context) {
|
||||
selectOrgRedirectUri = context.response.headers.get("Location") || "";
|
||||
cookieSetter(headers)(context);
|
||||
},
|
||||
});
|
||||
expect(selectOrgRedirectUri).toContain(`/select-organization`);
|
||||
expect(selectOrgRedirectUri).toContain(
|
||||
`client_id=${oauthClient.client_id}`,
|
||||
);
|
||||
expect(selectOrgRedirectUri).toContain(`scope=`);
|
||||
expect(selectOrgRedirectUri).toContain(`state=`);
|
||||
vi.stubGlobal("window", {
|
||||
location: {
|
||||
search: new URL(selectOrgRedirectUri, authServerBaseUrl).search,
|
||||
},
|
||||
});
|
||||
onTestFinished(() => {
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
selectedPostLogin = true;
|
||||
const continueRes = await serverClient.oauth2.continue(
|
||||
{
|
||||
postLogin: true,
|
||||
},
|
||||
{
|
||||
headers,
|
||||
throw: true,
|
||||
onResponse: cookieSetter(headers),
|
||||
},
|
||||
);
|
||||
expect(continueRes.url).toContain(redirectUri);
|
||||
expect(continueRes.url).toContain(`code=`);
|
||||
|
||||
selectedPostLogin = false;
|
||||
enablePostLogin = false;
|
||||
});
|
||||
|
||||
it("shall allow user to select an organization/team post login and consent", async ({
|
||||
onTestFinished,
|
||||
}) => {
|
||||
@@ -1487,6 +1568,7 @@ describe("oauth - prompt", async () => {
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
let consentRedirectUri = "";
|
||||
// Select Account and continue auth flow
|
||||
await serverClient.organization.setActive(
|
||||
{
|
||||
@@ -1495,22 +1577,12 @@ describe("oauth - prompt", async () => {
|
||||
},
|
||||
{
|
||||
headers,
|
||||
throw: true,
|
||||
onResponse: cookieSetter(headers),
|
||||
onResponse(context) {
|
||||
consentRedirectUri = context.response.headers.get("Location") || "";
|
||||
cookieSetter(headers)(context);
|
||||
},
|
||||
},
|
||||
);
|
||||
const selectedAccountRes = await serverClient.oauth2.continue(
|
||||
{
|
||||
postLogin: true,
|
||||
},
|
||||
{
|
||||
headers,
|
||||
throw: true,
|
||||
onResponse: cookieSetter(headers),
|
||||
},
|
||||
);
|
||||
expect(selectedAccountRes.redirect).toBeTruthy();
|
||||
const consentRedirectUri = selectedAccountRes?.url;
|
||||
expect(consentRedirectUri).toContain(`/consent`);
|
||||
expect(consentRedirectUri).toContain(`client_id=${oauthClient.client_id}`);
|
||||
expect(consentRedirectUri).toContain(`scope=`);
|
||||
|
||||
Reference in New Issue
Block a user