You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(auth): surface features.sso in public /auth/config (#2330)
* feat(auth): surface features.sso in public /auth/config
getPublicConfig() advertised every other auth capability flag (oidcProvider,
twoFactor, multiOrgEnabled, …) but omitted enterprise SSO, even though the
manager already computes whether @better-auth/sso is wired (OS_SSO_ENABLED /
plugins.sso). The login UI therefore had nothing to gate on and rendered the
"Sign in with SSO" button unconditionally; on a deployment without SSO wired,
clicking it only then surfaced "No SSO provider is configured for this email
domain."
features.sso is now resolved with the EXACT logic that decides whether the
plugin is mounted in buildPlugins(), so the advertised capability can never
disagree with the actual /sign-in/sso route. Tests cover default-off, config-on,
and OS_SSO_ENABLED env override.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* feat(auth): refine features.sso to provider-existence at /auth/config
Follow-up to the coarse features.sso flag: getPublicConfig() still returns the
"wired" capability (cheap, sync), but the /auth/config route now refines it to
"usable" via the new AuthManager.isSsoUsable() — wired AND >=1 sys_sso_provider
row exists. This hides the "Sign in with SSO" button not only when SSO is off
but also when it's enabled yet no IdP is configured yet (previously the button
showed and errored for everyone at click time).
isSsoUsable() only queries sys_sso_provider when wired and fails OPEN to the
wired flag on any introspection failure (no data engine, query throws), so the
login config endpoint never 500s. The coarse computation is factored into a
private isSsoWired() shared by getPublicConfig() and isSsoUsable(). Both the
plugin-auth route and the hono adapter /config path apply the refinement (the
latter guarded so it's a no-op against an older auth service). 5 new unit tests
cover not-wired, zero-providers, >=1 provider, no-engine fail-open, and
query-throws fail-open.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
0 commit comments