[PR #3125] [CLOSED] feat: add configurable OAuth state management #30262

Closed
opened 2026-04-17 21:24:10 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/3125
Author: @shaug
Created: 6/21/2025
Status: Closed

Base: mainHead: shaug/configurable-oauth-state-strategy


📝 Commits (4)

  • d87e61a feat: add configurable OAuth state management
  • 17528bc style: fix formatting issues from linter
  • 7e85648 Add OAuth state management documentation
  • b85d1f8 Add tests and docs for codeVerifier behavior

📊 Changes

9 files changed (+1079 additions, -38 deletions)

View changed files

📝 docs/content/docs/concepts/oauth.mdx (+231 -0)
📝 docs/content/docs/plugins/generic-oauth.mdx (+8 -4)
📝 docs/content/docs/plugins/oauth-proxy.mdx (+8 -4)
📝 docs/content/docs/reference/options.mdx (+34 -1)
📝 docs/content/docs/reference/security.mdx (+12 -2)
packages/better-auth/src/oauth2/state.test.ts (+539 -0)
📝 packages/better-auth/src/oauth2/state.ts (+100 -27)
📝 packages/better-auth/src/oauth2/types.ts (+117 -0)
📝 packages/better-auth/src/types/options.ts (+30 -0)

📄 Description

This PR addresses the cross-environment OAuth state management issue raised in #1819 by introducing a configurable state management system that enables stateless OAuth flows while maintaining full backward compatibility.

Changes

  • Add oauth.stateManagement configuration option with generateState and parseState functions
  • Add StateManagement interface with comprehensive JSDoc examples
  • Extract database-based state logic into generateVerificationState and parseVerificationState functions
  • Modify generateState and parseState to support custom state management with DB fallback
  • Add comprehensive test coverage for both custom and fallback scenarios

Backward Compatibility

  • When no custom state management is configured, behavior is identical to before
  • All existing OAuth flows continue to work unchanged
  • Database-based state management remains the default

Usage

// Enable stateless state management
const auth = betterAuth({
  oauth: {
    stateManagement: {
      generateState: async (ctx, payload) => {
        const encryptedState = await symmetricEncrypt({
          key: ctx.context.secret,
          data: JSON.stringify(payload)
        });
        return encodeURIComponent(encryptedState);
      },
      parseState: async (ctx, state) => {
        try {
          const decryptedState = await symmetricDecrypt({
            key: ctx.context.secret,
            data: decodeURIComponent(state)
          });
          return JSON.parse(decryptedState);
        } catch {
          return undefined; // Fallback to database
        }
      }
    }
  }
});

This enables cross-environment OAuth flows where state can be passed between different environments without requiring shared database access (especially when used with the oAuthProxy plugin).

Closes #1819


🔄 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/3125 **Author:** [@shaug](https://github.com/shaug) **Created:** 6/21/2025 **Status:** ❌ Closed **Base:** `main` ← **Head:** `shaug/configurable-oauth-state-strategy` --- ### 📝 Commits (4) - [`d87e61a`](https://github.com/better-auth/better-auth/commit/d87e61a2b97446179868e56d688ed2597409769e) feat: add configurable OAuth state management - [`17528bc`](https://github.com/better-auth/better-auth/commit/17528bcc4395973680ad69b890ba219f8b547c2f) style: fix formatting issues from linter - [`7e85648`](https://github.com/better-auth/better-auth/commit/7e85648b74303dcf04036f027558b27b533facce) Add OAuth state management documentation - [`b85d1f8`](https://github.com/better-auth/better-auth/commit/b85d1f8230ea4cdd59097e45c351c83c96a47c50) Add tests and docs for codeVerifier behavior ### 📊 Changes **9 files changed** (+1079 additions, -38 deletions) <details> <summary>View changed files</summary> 📝 `docs/content/docs/concepts/oauth.mdx` (+231 -0) 📝 `docs/content/docs/plugins/generic-oauth.mdx` (+8 -4) 📝 `docs/content/docs/plugins/oauth-proxy.mdx` (+8 -4) 📝 `docs/content/docs/reference/options.mdx` (+34 -1) 📝 `docs/content/docs/reference/security.mdx` (+12 -2) ➕ `packages/better-auth/src/oauth2/state.test.ts` (+539 -0) 📝 `packages/better-auth/src/oauth2/state.ts` (+100 -27) 📝 `packages/better-auth/src/oauth2/types.ts` (+117 -0) 📝 `packages/better-auth/src/types/options.ts` (+30 -0) </details> ### 📄 Description This PR addresses the cross-environment OAuth state management issue raised in #1819 by introducing a configurable state management system that enables stateless OAuth flows while maintaining full backward compatibility. ## Changes - Add `oauth.stateManagement` configuration option with `generateState` and `parseState` functions - Add `StateManagement` interface with comprehensive JSDoc examples - Extract database-based state logic into `generateVerificationState` and `parseVerificationState` functions - Modify `generateState` and `parseState` to support custom state management with DB fallback - Add comprehensive test coverage for both custom and fallback scenarios ## Backward Compatibility - When no custom state management is configured, behavior is identical to before - All existing OAuth flows continue to work unchanged - Database-based state management remains the default ## Usage ```ts // Enable stateless state management const auth = betterAuth({ oauth: { stateManagement: { generateState: async (ctx, payload) => { const encryptedState = await symmetricEncrypt({ key: ctx.context.secret, data: JSON.stringify(payload) }); return encodeURIComponent(encryptedState); }, parseState: async (ctx, state) => { try { const decryptedState = await symmetricDecrypt({ key: ctx.context.secret, data: decodeURIComponent(state) }); return JSON.parse(decryptedState); } catch { return undefined; // Fallback to database } } } } }); ``` This enables cross-environment OAuth flows where state can be passed between different environments without requiring shared database access (especially when used with the oAuthProxy plugin). Closes #1819 --- <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-17 21:24:10 -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#30262