[BUG] GitHub OAuth Provider Ignores prompt Configuration #1313

Closed
opened 2026-03-13 08:32:26 -05:00 by GiteaMirror · 0 comments
Owner

Originally created by @AtelyPham on GitHub (Jun 5, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Create a better-auth configuration with GitHub OAuth provider and set the prompt option:
import { betterAuth } from "better-auth"
import { github } from "better-auth/providers/github"

export const auth = betterAuth({
  socialProviders: {
    github: github({
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
      prompt: "select_account+consent" // This should force account selection and consent
    })
  }
})
  1. Initiate GitHub OAuth sign-in from your frontend
  2. Observe that the GitHub OAuth authorization URL does NOT include the prompt=select_account+consent parameter
  3. The OAuth flow behaves with default GitHub behavior instead of the configured prompt behavior

Current vs. Expected behavior

Current Behavior:

  • The prompt option configured in the GitHub provider options is completely ignored
  • GitHub OAuth authorization URL is generated without the prompt query parameter
  • OAuth flow uses GitHub's default behavior (no account selection prompt)

Expected Behavior:

  • The prompt option from provider configuration should be passed to the authorization URL
  • GitHub OAuth authorization URL should include prompt=select_account+consent parameter
  • OAuth flow should force account selection and consent as configured

Root Cause Analysis:
After investigating the source code, I found the issue in packages/better-auth/src/social-providers/github.ts at lines 56-68:

createAuthorizationURL({ state, scopes, loginHint, redirectURI }) {
  const _scopes = options.disableDefaultScope
    ? []
    : ["read:user", "user:email"];
  options.scope && _scopes.push(...options.scope);
  scopes && _scopes.push(...scopes);
  return createAuthorizationURL({
    id: "github",
    options,
    authorizationEndpoint: "https://github.com/login/oauth/authorize",
    scopes: _scopes,
    state,
    redirectURI,
    loginHint,
    // ❌ Missing: prompt parameter is not passed here
  });
},

The createAuthorizationURL function in packages/better-auth/src/oauth2/create-authorization-url.ts already supports the prompt parameter and has proper handling logic:

if (prompt) {
  url.searchParams.set("prompt", prompt);
} else if (options.prompt) {
  url.searchParams.set("prompt", options.prompt);
}

However, the GitHub provider doesn't pass the prompt parameter to this function, so the configured prompt value is never used.

What version of Better Auth are you using?

1.2.8

Provide environment information

- OS: macOS 15.5
- Node.js: v22.13.1
- Package Manager: pnpm
- Framework: Remix.js
- Browser: Chrome

Which area(s) are affected? (Select all that apply)

Client, Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"
import { github } from "better-auth/providers/github"

export const auth = betterAuth({
  database: {
    // database config
  },
  socialProviders: {
    github: github({
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
      prompt: "select_account+consent", // This configuration is ignored
      scope: ["read:user", "user:email"]
    })
  }
})

Additional context

  • This issue likely affects other OAuth providers as well if they have similar implementations
  • The prompt option is properly defined in the ProviderOptions type with valid values: "select_account" | "consent" | "login" | "none" | "select_account+consent"
  • This is a breaking issue for applications that require specific OAuth prompt behaviors (e.g., forcing account selection for multi-account scenarios)
  • The createAuthorizationURL utility function already has the proper logic to handle this parameter, so the fix is minimal and safe

🔧 Proposed Fix

The fix should be straightforward - pass the prompt parameter from options.prompt to the createAuthorizationURL function in the GitHub provider:

// In packages/better-auth/src/social-providers/github.ts
createAuthorizationURL({ state, scopes, loginHint, redirectURI }) {
  const _scopes = options.disableDefaultScope
    ? []
    : ["read:user", "user:email"];
  options.scope && _scopes.push(...options.scope);
  scopes && _scopes.push(...scopes);
  return createAuthorizationURL({
    id: "github",
    options,
    authorizationEndpoint: "https://github.com/login/oauth/authorize",
    scopes: _scopes,
    state,
    redirectURI,
    loginHint,
    prompt: options.prompt, // ✅ Add this line
  });
},
Originally created by @AtelyPham on GitHub (Jun 5, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Create a better-auth configuration with GitHub OAuth provider and set the `prompt` option: ```typescript import { betterAuth } from "better-auth" import { github } from "better-auth/providers/github" export const auth = betterAuth({ socialProviders: { github: github({ clientId: process.env.GITHUB_CLIENT_ID!, clientSecret: process.env.GITHUB_CLIENT_SECRET!, prompt: "select_account+consent" // This should force account selection and consent }) } }) ``` 2. Initiate GitHub OAuth sign-in from your frontend 3. Observe that the GitHub OAuth authorization URL does NOT include the `prompt=select_account+consent` parameter 4. The OAuth flow behaves with default GitHub behavior instead of the configured prompt behavior ### Current vs. Expected behavior **Current Behavior:** - The `prompt` option configured in the GitHub provider options is completely ignored - GitHub OAuth authorization URL is generated without the `prompt` query parameter - OAuth flow uses GitHub's default behavior (no account selection prompt) **Expected Behavior:** - The `prompt` option from provider configuration should be passed to the authorization URL - GitHub OAuth authorization URL should include `prompt=select_account+consent` parameter - OAuth flow should force account selection and consent as configured **Root Cause Analysis:** After investigating the source code, I found the issue in `packages/better-auth/src/social-providers/github.ts` at lines 56-68: ```typescript createAuthorizationURL({ state, scopes, loginHint, redirectURI }) { const _scopes = options.disableDefaultScope ? [] : ["read:user", "user:email"]; options.scope && _scopes.push(...options.scope); scopes && _scopes.push(...scopes); return createAuthorizationURL({ id: "github", options, authorizationEndpoint: "https://github.com/login/oauth/authorize", scopes: _scopes, state, redirectURI, loginHint, // ❌ Missing: prompt parameter is not passed here }); }, ``` The `createAuthorizationURL` function in `packages/better-auth/src/oauth2/create-authorization-url.ts` already supports the `prompt` parameter and has proper handling logic: ```typescript if (prompt) { url.searchParams.set("prompt", prompt); } else if (options.prompt) { url.searchParams.set("prompt", options.prompt); } ``` However, the GitHub provider doesn't pass the `prompt` parameter to this function, so the configured prompt value is never used. ### What version of Better Auth are you using? 1.2.8 ### Provide environment information ```bash - OS: macOS 15.5 - Node.js: v22.13.1 - Package Manager: pnpm - Framework: Remix.js - Browser: Chrome ``` ### Which area(s) are affected? (Select all that apply) Client, Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" import { github } from "better-auth/providers/github" export const auth = betterAuth({ database: { // database config }, socialProviders: { github: github({ clientId: process.env.GITHUB_CLIENT_ID!, clientSecret: process.env.GITHUB_CLIENT_SECRET!, prompt: "select_account+consent", // This configuration is ignored scope: ["read:user", "user:email"] }) } }) ``` ### Additional context - This issue likely affects other OAuth providers as well if they have similar implementations - The `prompt` option is properly defined in the `ProviderOptions` type with valid values: `"select_account" | "consent" | "login" | "none" | "select_account+consent"` - This is a breaking issue for applications that require specific OAuth prompt behaviors (e.g., forcing account selection for multi-account scenarios) - The `createAuthorizationURL` utility function already has the proper logic to handle this parameter, so the fix is minimal and safe ## 🔧 Proposed Fix The fix should be straightforward - pass the `prompt` parameter from `options.prompt` to the `createAuthorizationURL` function in the GitHub provider: ```typescript // In packages/better-auth/src/social-providers/github.ts createAuthorizationURL({ state, scopes, loginHint, redirectURI }) { const _scopes = options.disableDefaultScope ? [] : ["read:user", "user:email"]; options.scope && _scopes.push(...options.scope); scopes && _scopes.push(...scopes); return createAuthorizationURL({ id: "github", options, authorizationEndpoint: "https://github.com/login/oauth/authorize", scopes: _scopes, state, redirectURI, loginHint, prompt: options.prompt, // ✅ Add this line }); }, ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1313