[PR #8815] [MERGED] fix(oauth-provider): return JSON redirects from post-login OAuth continuation #25132

Closed
opened 2026-04-15 22:44:07 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/8815
Author: @gustavovalverde
Created: 3/28/2026
Status: Merged
Merged: 3/28/2026
Merged by: @gustavovalverde

Base: mainHead: fix/oauth-provider-cors-redirect


📝 Commits (2)

  • 15f259a fix(oauth-provider): detect form POST as navigation in authorize endpoint
  • 316c011 test(oauth-provider): cover continuation redirect regressions

📊 Changes

4 files changed (+577 additions, -38 deletions)

View changed files

📝 packages/oauth-provider/src/authorize.ts (+22 -11)
📝 packages/oauth-provider/src/continue.ts (+1 -0)
📝 packages/oauth-provider/src/oauth.test.ts (+541 -27)
📝 packages/oauth-provider/src/oauth.ts (+13 -0)

📄 Description

Summary

Fixes #7041.
Closes #7280.

When authorizeEndpoint runs inside the OAuth after-hook (post sign-in), 2 bugs produce raw 302 redirects that browsers cannot follow under CORS constraints:

  • After-hook omission: the after-hook was the only authorizeEndpoint caller that did not signal a JSON-capable context. consent.ts and continue.ts already set Accept: application/json; the after-hook did not.
  • Error-path bypass: 11 early-validation branches in authorizeEndpoint threw ctx.redirect() directly, bypassing handleRedirect and its Sec-Fetch-Mode / Accept check. A client deleted or disabled between authorize and sign-in would always produce an unguarded 302.

The fix is scoped to 2 mechanisms:

  • Route every error redirect through handleRedirect, which returns JSON when the request is fetch-based and falls back to 302 for browser navigations.
  • Set Accept: application/json in the after-hook only when Sec-Fetch-Mode is not navigate, preserving 302 behavior for server-rendered form logins.
  • Add the same missing header in continue.ts:created(), matching the existing pattern in selected() and postLogin().

Summary by cubic

Fixes CORS failures after OAuth sign-in by returning JSON redirects for fetch-based flows while preserving 302 redirects for real navigations. Early error redirects now go through handleRedirect, and the post-login after-hook in oauth-provider sets Accept: application/json only for non-navigation requests.

  • Bug Fixes
    • Routed all early-validation redirects in authorizeEndpoint through handleRedirect to return JSON when appropriate.
    • In the after-hook (oauth.ts), detect navigations via Sec-Fetch-Mode: navigate or HTML Accept types (text/html, application/xhtml+xml); otherwise set Accept: application/json.
    • Added the missing Accept: application/json header in continue.ts:created() and expanded tests to cover continuation and post-login redirect behavior (JSON vs 302), including client deleted/disabled cases.

Written for commit 316c011c1e. Summary will update on new commits.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/8815 **Author:** [@gustavovalverde](https://github.com/gustavovalverde) **Created:** 3/28/2026 **Status:** ✅ Merged **Merged:** 3/28/2026 **Merged by:** [@gustavovalverde](https://github.com/gustavovalverde) **Base:** `main` ← **Head:** `fix/oauth-provider-cors-redirect` --- ### 📝 Commits (2) - [`15f259a`](https://github.com/better-auth/better-auth/commit/15f259a9518ce26a1603a14f1e8276b4548c337b) fix(oauth-provider): detect form POST as navigation in authorize endpoint - [`316c011`](https://github.com/better-auth/better-auth/commit/316c011c1eb8cc72cd25b138e7097469069b912d) test(oauth-provider): cover continuation redirect regressions ### 📊 Changes **4 files changed** (+577 additions, -38 deletions) <details> <summary>View changed files</summary> 📝 `packages/oauth-provider/src/authorize.ts` (+22 -11) 📝 `packages/oauth-provider/src/continue.ts` (+1 -0) 📝 `packages/oauth-provider/src/oauth.test.ts` (+541 -27) 📝 `packages/oauth-provider/src/oauth.ts` (+13 -0) </details> ### 📄 Description ## Summary Fixes #7041. Closes #7280. When `authorizeEndpoint` runs inside the OAuth after-hook (post sign-in), 2 bugs produce raw 302 redirects that browsers cannot follow under CORS constraints: * **After-hook omission:** the after-hook was the only `authorizeEndpoint` caller that did not signal a JSON-capable context. `consent.ts` and `continue.ts` already set `Accept: application/json`; the after-hook did not. * **Error-path bypass:** 11 early-validation branches in `authorizeEndpoint` threw `ctx.redirect()` directly, bypassing `handleRedirect` and its `Sec-Fetch-Mode` / `Accept` check. A client deleted or disabled between authorize and sign-in would always produce an unguarded 302. The fix is scoped to 2 mechanisms: * Route every error redirect through `handleRedirect`, which returns JSON when the request is fetch-based and falls back to 302 for browser navigations. * Set `Accept: application/json` in the after-hook only when `Sec-Fetch-Mode` is not `navigate`, preserving 302 behavior for server-rendered form logins. * Add the same missing header in `continue.ts:created()`, matching the existing pattern in `selected()` and `postLogin()`. <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Fixes CORS failures after OAuth sign-in by returning JSON redirects for fetch-based flows while preserving 302 redirects for real navigations. Early error redirects now go through `handleRedirect`, and the post-login after-hook in `oauth-provider` sets `Accept: application/json` only for non-navigation requests. - **Bug Fixes** - Routed all early-validation redirects in `authorizeEndpoint` through `handleRedirect` to return JSON when appropriate. - In the after-hook (`oauth.ts`), detect navigations via `Sec-Fetch-Mode: navigate` or HTML `Accept` types (`text/html`, `application/xhtml+xml`); otherwise set `Accept: application/json`. - Added the missing `Accept: application/json` header in `continue.ts:created()` and expanded tests to cover continuation and post-login redirect behavior (JSON vs 302), including client deleted/disabled cases. <sup>Written for commit 316c011c1eb8cc72cd25b138e7097469069b912d. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-15 22:44:07 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#25132