Repository navigation
fix(auth): login silent-failure UX — SSO pending states, redirect-URL contract, OAuth callback error banner (#2458 item 1) - #2468
Merged
Conversation
… contract, OAuth callback error banner (#2458 item 1) Three UI gaps let a login "succeed" or fail with zero feedback: - SocialSignInButtons: provider buttons ("Continue with ObjectStack") had no pending state and swallowed a sign-in call that resolved without navigating. Buttons now disable + spin while in flight, block double-clicks, and surface failures inline. - createAuthClient.signInWithProvider: resolving without a redirect URL (oidc + social paths) was a silent no-op — now throws so callers can render the error. - LoginForm "Sign in with SSO": raw fetch had no pending state — added. - LoginPage: a failed OAuth callback (expired/replayed state, IdP error) redirects back to the login page with ?error=<code>; the page now renders it as a visible banner instead of a silent login form. Paired framework change points better-auth onAPIError.errorURL at /_console/login so the code survives the redirect (today it dies on the root redirect: the env callback 302s to /?error=state_mismatch and the root→console hop drops the query). Live-verified on the run-stack rig (cloud 4900 / env 5900): wrong-password inline error, plain login redirect, full env→SSO→cloud→env OAuth hand-off, and the state_mismatch silent dead-end reproduced then surfaced. Refs #2458 (item 1) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes item 1 (🔴 登录提交"无声失败") of #2458.
Ownership verdict
The login surface is objectui-owned — the console SPA (
apps/console+@object-ui/auth) serves/_console/loginon both the cloud (:4900) and every env host; framework's better-auth server side behaves as designed with one exception (below). Live re-investigation on the run-stack rig found:followOauthAuthorize, fix(auth): cloud login SPA follows the oauth2/authorize redirect (env→cloud SSO) #2008) — these were live-verified working. Part of what the three test sessions saw was a stale served console bundle (the rig node-resolves@objectstack/consoletoframework/packages/console/dist, bypassing run-stack's overlay) plus click/typing automation artifacts.statego stale (10-minexp, single-use state — easy in a slow real-world session), the cloud still issues a code, the env callback rejects withstate_mismatch, and better-auth's default error redirect (/?error=state_mismatch) loses its query on the root→console hop. The user who just typed a correct password lands on a silent login form — exactly the reported symptom (the env and cloud login forms are visually identical).Changes
SocialSignInButtons: pending spinner + disabled whilesignInWithProvideris in flight, double-click guard, inline failure surfacing (button re-enables only on failure — success ends in navigation).createAuthClient.signInWithProvider: throws when the server response carries no redirect URL (bothoidcandsocialpaths) instead of resolving silently.LoginForm"Sign in with SSO": pending state on the raw/sign-in/ssofetch.LoginPage: renders?error=/?error_description=(better-auth OAuth callback failure codes) as a visibleAuthErrorBanner— zh/en strings added (auth.login.errors.oauthCallbackFailed).onAPIError.errorURL→/_console/login) makes the server land callback errors where this banner is. The banner is inert until that merges; merge this UI PR first.Verification (live browser on the run-stack rig, fixed bundle overlaid)
?error=state_mismatchon loginScoped tests:
packages/auth(LoginForm / SocialSignInButtons / createAuthClient) +apps/consoleLoginPage banner — 53 tests green.🤖 Generated with Claude Code