fix(auth): address second-round review findings
- OAuth-cancel feedback now keys on the live session, not link_uid: ANY signed-in cancel (add-another-account via /auth/login, link, or upgrade) redirects to /?oauth=cancelled and gets a neutral "Google sign-in was cancelled" toast — the add-account path set no marker and was silent, and the shared ?link= message wrongly called an upgrade "account linking" - drop 127.0.0.1 from the dev OAuth host allowlist: only the localhost callbacks are registered in the Google console, so a 127.0.0.1 origin now falls back to the fixed callback instead of a redirect_uri_mismatch - Welcome: extract the shared goResend handler (banner CTA + sign-in link) and merge the two adjacent signin-only blocks
This commit is contained in:
+12
-9
@@ -249,10 +249,11 @@ def upsert_pending_invite(db: Session, email: str) -> Invite | None:
|
||||
# Local-dev origins allowed to drive the OAuth redirect_uri from the request Host. The Vite dev
|
||||
# server (:5173) proxies /auth to the backend (:8080) preserving the Host header, and the session
|
||||
# cookie is port-agnostic — so a flow started on :5173 can come back to :5173 instead of always
|
||||
# landing on the fixed :8080 callback. Both must also be registered in the Google console.
|
||||
_DEV_OAUTH_HOSTS = frozenset(
|
||||
{"localhost:5173", "localhost:8080", "127.0.0.1:5173", "127.0.0.1:8080"}
|
||||
)
|
||||
# landing on the fixed :8080 callback. Only the localhost variants are listed: they must ALSO be
|
||||
# registered as redirect URIs in the Google console, and Google rejects an unregistered one with
|
||||
# redirect_uri_mismatch. A 127.0.0.1 origin isn't registered, so it deliberately falls through to
|
||||
# the fixed configured callback (which is registered) rather than producing a mismatch.
|
||||
_DEV_OAUTH_HOSTS = frozenset({"localhost:5173", "localhost:8080"})
|
||||
|
||||
|
||||
def _oauth_redirect_uri(request: Request) -> str:
|
||||
@@ -309,12 +310,14 @@ async def callback(
|
||||
token = await client.authorize_access_token(request)
|
||||
except OAuthError as exc:
|
||||
# The user cancelled or denied consent at Google — land back with a friendly notice instead
|
||||
# of a raw 400 JSON error page. A link/upgrade cancel is an ALREADY-signed-in user who never
|
||||
# sees the pre-auth login banner, so route it through the ?link= channel App.tsx surfaces as
|
||||
# a toast; a plain sign-in cancel lands on the login page with the oauth_cancelled banner.
|
||||
# of a raw 400 JSON error page. An already-signed-in user (adding another account via
|
||||
# /auth/login, or linking/upgrading via /auth/link|upgrade) never sees the pre-auth login
|
||||
# banner, so surface a neutral toast via ?oauth=cancelled; a fresh sign-in cancel lands on
|
||||
# the login page with the oauth_cancelled banner instead. Keyed on the live session, not on
|
||||
# link_uid, so the add-account path (no marker) is covered too.
|
||||
log.info("Google OAuth cancelled/failed: %s", exc.error)
|
||||
if link_uid is not None:
|
||||
return RedirectResponse(url="/?link=cancelled")
|
||||
if request.session.get("user_id") is not None:
|
||||
return RedirectResponse(url="/?oauth=cancelled")
|
||||
return RedirectResponse(url="/?login=oauth_cancelled")
|
||||
|
||||
userinfo = token.get("userinfo")
|
||||
|
||||
@@ -30,7 +30,6 @@ def test_dev_known_host_returns_to_that_origin(monkeypatch):
|
||||
monkeypatch.setattr(auth, "settings", _dev_settings())
|
||||
assert auth._oauth_redirect_uri(_req("localhost:5173")) == "http://localhost:5173/auth/callback"
|
||||
assert auth._oauth_redirect_uri(_req("localhost:8080")) == "http://localhost:8080/auth/callback"
|
||||
assert auth._oauth_redirect_uri(_req("127.0.0.1:5173")) == "http://127.0.0.1:5173/auth/callback"
|
||||
|
||||
|
||||
def test_dev_host_is_case_insensitive(monkeypatch):
|
||||
@@ -41,6 +40,9 @@ def test_dev_host_is_case_insensitive(monkeypatch):
|
||||
def test_dev_unknown_or_missing_host_falls_back_to_configured(monkeypatch):
|
||||
monkeypatch.setattr(auth, "settings", _dev_settings())
|
||||
# An origin not on the allowlist (or a request with no Host) must not drive the redirect.
|
||||
# 127.0.0.1 is deliberately NOT allowlisted (not registered in the Google console), so it falls
|
||||
# back to the fixed configured callback rather than producing a redirect_uri_mismatch.
|
||||
assert auth._oauth_redirect_uri(_req("127.0.0.1:5173")) == "http://localhost:8080/auth/callback"
|
||||
assert auth._oauth_redirect_uri(_req("evil.example.com")) == "http://localhost:8080/auth/callback"
|
||||
assert auth._oauth_redirect_uri(_req(None)) == "http://localhost:8080/auth/callback"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user