Skip to content

refactor: use zod for oidc params#771

Merged
steveiliop56 merged 4 commits into
mainfrom
refactor/oidc-params
Apr 10, 2026
Merged

refactor: use zod for oidc params#771
steveiliop56 merged 4 commits into
mainfrom
refactor/oidc-params

Conversation

@steveiliop56
Copy link
Copy Markdown
Member

@steveiliop56 steveiliop56 commented Apr 8, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Improved validation and clearer error messages for OIDC requests, reducing authorization failures.
    • More reliable redirects during login, TOTP, and authorize flows, preserving and encoding OIDC query data correctly.
  • Refactor

    • Unified OIDC parameter handling and parsing, improving scope extraction and OAuth redirect URL generation for user flows.

@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Apr 8, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 8, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 999c8531-a557-413d-90af-49c7a5640e87

📥 Commits

Reviewing files that changed from the base of the PR and between a869fb7 and 05b20a2.

📒 Files selected for processing (1)
  • frontend/src/pages/login-page.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/pages/login-page.tsx

📝 Walkthrough

Walkthrough

Replaces manual OIDC param assembly with Zod validation: useOIDCParams now validates URLSearchParams via oidcParamsSchema and returns { values, issues, isOidc, compiled }. Pages were updated to consume oidcParams and read redirect_uri directly from searchParams where applicable.

Changes

Cohort / File(s) Summary
OIDC Hook Validation
frontend/src/lib/hooks/oidc.ts
Removed exported OIDCValues/IuseOIDCParams; added exported oidcParamsSchema (Zod). useOIDCParams now builds an object from params.entries() and uses oidcParamsSchema.safeParse; returns { values, issues, isOidc, compiled } on success/failure instead of missingParams.
Pages — authorize / login / totp
frontend/src/pages/authorize-page.tsx, frontend/src/pages/login-page.tsx, frontend/src/pages/totp-page.tsx
Pages now use a single oidcParams object. client_id for queries and mutation keys/payloads read from oidcParams.values. Redirects and validation checks use oidcParams.isOidc / oidcParams.compiled and oidcParams.issues; redirect_uri is read directly from searchParams. Scope parsing moved to split oidcParams.values.scope.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Browser as Browser
    participant Hook as useOIDCParams
    participant Page as Page (Authorize/Login/TOTP)
    participant API as Server API
    Browser->>Hook: provide URLSearchParams
    Hook->>Hook: validate via oidcParamsSchema (Zod)
    Hook-->>Page: return oidcParams { values, isOidc, compiled, issues }
    Page->>API: fetch client (/api/oidc/clients/:id) [if isOidc]
    Page->>API: post authorize (/api/oidc/authorize) with oidcParams.values
    API-->>Page: response (client info / authorize result)
    Page->>Browser: navigate to /authorize?{compiled} or /continue[?redirect_uri]
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~18 minutes

Possibly related PRs

Suggested reviewers

  • Rycochet

Poem

🐰 I hopped through query strings under moonlit beams,

Zod stitched tokens into tidy seams,
No missing keys, no puzzled nights,
Redirects sing and validation lights,
A carrot cheer for parsed delights 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'refactor: use zod for oidc params' accurately and concisely describes the main change—replacing manual OIDC params handling with Zod validation across the codebase.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/oidc-params

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 8, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 19.82%. Comparing base (2c1b62f) to head (05b20a2).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #771   +/-   ##
=======================================
  Coverage   19.82%   19.82%           
=======================================
  Files          50       50           
  Lines        3960     3960           
=======================================
  Hits          785      785           
  Misses       3104     3104           
  Partials       71       71           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/lib/hooks/oidc.ts`:
- Line 12: Remove the unsupported prompt field from the OIDC zod schema in
frontend/src/lib/hooks/oidc.ts: delete or comment out the line that adds prompt:
z.string().optional() so the frontend no longer preserves prompt values the
backend ignores; instead add a TODO/note referencing that prompt will be
re-added once AuthorizeRequest in oidc_service.go gains a prompt field and
prompt semantics are implemented.
- Around line 4-7: The OIDC param schema currently allows empty strings because
it uses z.string(); update each required field (scope, response_type, client_id,
redirect_uri) to enforce non-empty values by replacing z.string() with
z.string().nonempty() (or .min(1)) so the frontend validation rejects empty
parameters (also adjust any related type-guard or helper that sets isOidc to
rely on the tightened schema if present).

In `@frontend/src/pages/authorize-page.tsx`:
- Around line 80-82: The request URL interpolates a raw OIDC client_id into the
path (in the authorize-page component) which breaks routing for IDs containing
'/', ':', '?' etc.; fix by URL-encoding the client_id before building the path
(use encodeURIComponent on oidcParams.values.client_id where the fetch to
`/api/oidc/clients/${...}` is constructed) so the fetch uses
`/api/oidc/clients/${encodeURIComponent(oidcParams.values.client_id)}` and
safely looks up the client.

In `@frontend/src/pages/login-page.tsx`:
- Around line 109-110: The redirect to the TOTP page currently forwards only
redirect_uri, losing the rest of the OIDC query params; update the
window.location.replace call in frontend/src/pages/login-page.tsx (the call that
builds `/totp...`) to preserve and forward the full original query string (e.g.,
use window.location.search or construct the entire query from location) so
client_id, scope, state, nonce, etc. are included when landing on /totp and the
TOTP success path can detect OIDC and continue to /authorize.
- Around line 174-177: The guard currently treats undefined redirectUri as
non-empty because it checks redirectUri !== "", so logged-in users without a
redirect_uri get redirected incorrectly; update the condition in the login-page
component to require a truthy string for redirectUri (e.g., use if (isLoggedIn
&& redirectUri) or explicitly check typeof redirectUri === "string" &&
redirectUri !== "") so the Navigate block (and its use of
encodeURIComponent(redirectUri)) only runs when redirectUri is present.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b4746966-fb13-448a-8d3e-c9e9c55e004c

📥 Commits

Reviewing files that changed from the base of the PR and between 646e24d and ff64d64.

📒 Files selected for processing (4)
  • frontend/src/lib/hooks/oidc.ts
  • frontend/src/pages/authorize-page.tsx
  • frontend/src/pages/login-page.tsx
  • frontend/src/pages/totp-page.tsx

Comment thread frontend/src/lib/hooks/oidc.ts Outdated
Comment thread frontend/src/lib/hooks/oidc.ts Outdated
Comment thread frontend/src/pages/authorize-page.tsx
Comment thread frontend/src/pages/login-page.tsx
Comment thread frontend/src/pages/login-page.tsx Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
frontend/src/lib/hooks/oidc.ts (1)

3-12: Use .min(1) instead of .nonempty() for string validation.

Zod v3.20+ deprecated .nonempty() on strings in favor of .min(1). The project uses Zod v4.3.6, so this deprecation applies. While .nonempty() still works, updating to .min(1) aligns with current Zod best practices.

♻️ Suggested change
 export const oidcParamsSchema = z.object({
-  scope: z.string().nonempty(),
-  response_type: z.string().nonempty(),
-  client_id: z.string().nonempty(),
-  redirect_uri: z.string().nonempty(),
+  scope: z.string().min(1),
+  response_type: z.string().min(1),
+  client_id: z.string().min(1),
+  redirect_uri: z.string().min(1),
   state: z.string().optional(),
   nonce: z.string().optional(),
   code_challenge: z.string().optional(),
   code_challenge_method: z.string().optional(),
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/lib/hooks/oidc.ts` around lines 3 - 12, Replace deprecated
.nonempty() uses with .min(1) on required string fields in the oidcParamsSchema:
update scope, response_type, client_id, and redirect_uri validators to use
.min(1) instead of .nonempty() so the schema conforms to Zod v3.20+/v4 semantics
while leaving optional fields (state, nonce, code_challenge,
code_challenge_method) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@frontend/src/lib/hooks/oidc.ts`:
- Around line 3-12: Replace deprecated .nonempty() uses with .min(1) on required
string fields in the oidcParamsSchema: update scope, response_type, client_id,
and redirect_uri validators to use .min(1) instead of .nonempty() so the schema
conforms to Zod v3.20+/v4 semantics while leaving optional fields (state, nonce,
code_challenge, code_challenge_method) unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b9f08d29-a767-41ae-90a2-6d402045383a

📥 Commits

Reviewing files that changed from the base of the PR and between ff64d64 and 31b86b4.

📒 Files selected for processing (3)
  • frontend/src/lib/hooks/oidc.ts
  • frontend/src/pages/authorize-page.tsx
  • frontend/src/pages/login-page.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/src/pages/login-page.tsx
  • frontend/src/pages/authorize-page.tsx

@steveiliop56 steveiliop56 merged commit 8b91ce0 into main Apr 10, 2026
8 checks passed
@Rycochet Rycochet deleted the refactor/oidc-params branch April 26, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants