Skip to content

fix: handle missing OIDC auth request gracefully#74

Merged
mattdjenkinson merged 3 commits intomainfrom
fix/handle-missing-oidc-auth-request
Apr 20, 2026
Merged

fix: handle missing OIDC auth request gracefully#74
mattdjenkinson merged 3 commits intomainfrom
fix/handle-missing-oidc-auth-request

Conversation

@mattdjenkinson
Copy link
Copy Markdown
Collaborator

The GET /login route called getAuthRequest() without error handling. When a request arrived with an expired or invalid authRequest ID, the Zitadel OIDC service returned a NOT_FOUND gRPC error that propagated as an unhandled ConnectError, crashing the route handler with a 500.

Wrap the call in try/catch and add a null guard, returning a 400 JSON response instead. This matches the existing pattern used by the SAML branch which already checks for a missing samlRequest.

Fixes: https://sentry.prod.env.datum.net/organizations/sentry/issues/2054/?alert_rule_id=19&alert_type=issue&notification_uuid=852b3420-6a90-49e9-8246-540ffe41b7d2&project=6&referrer=slack

The GET /login route called getAuthRequest() without error handling.
When a request arrived with an expired or invalid authRequest ID, the
Zitadel OIDC service returned a NOT_FOUND gRPC error that propagated
as an unhandled ConnectError, crashing the route handler with a 500.

Wrap the call in try/catch and add a null guard, returning a 400 JSON
response instead. This matches the existing pattern used by the SAML
branch which already checks for a missing samlRequest.

Made-with: Cursor
@mattdjenkinson mattdjenkinson requested review from a team, felixwidjaja, kevwilliams, scotwells, yahyafakhroji and zachsmith1 and removed request for a team April 16, 2026 12:42
Comment thread apps/login/src/app/login/route.ts Outdated

if (!authRequest) {
return NextResponse.json(
{ error: "Auth request not found" },
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the error end users would end up seeing?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah - i've pushed another commit that improves the error messaging.

Previously, when the /login route encountered errors (expired auth
request, missing SAML request, unreachable IDP, no request params),
it returned raw JSON like {"error":"Auth request not found or expired"}
directly to the browser. Since this route is reached via browser
navigation (not a fetch() call), users saw unhelpful raw JSON text.

Replace all user-facing NextResponse.json() error responses with
redirects to a new /error page that renders inside the existing boxed
card layout with a clear title and actionable message.

The catch block for getAuthRequest now inspects the ConnectError code
from Zitadel to provide specific guidance: expired sessions (NOT_FOUND),
permission issues, service unavailability, and timeouts each get a
tailored message.

The two JSON responses intentionally left unchanged:
- RSC check: internal Next.js safeguard, never user-facing
- Prompt.NONE: OIDC spec requires no UI for silent auth; the calling
  application handles this programmatically

Made-with: Cursor
scotwells
scotwells previously approved these changes Apr 16, 2026
kevwilliams
kevwilliams previously approved these changes Apr 17, 2026
ConnectError is only re-exported as a type from @zitadel/client
(export type { ConnectError }), so it cannot be used with instanceof
at runtime. Check for the error shape via property inspection instead.

Made-with: Cursor
@mattdjenkinson mattdjenkinson merged commit 7e4965b into main Apr 20, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants