Skip to content

Conversation

@kashish00208
Copy link

@kashish00208 kashish00208 commented Dec 3, 2025

Closes #19

This PR adds the OktaProvider implementation to Stack Auth, extending the existing OAuth provider system.
It introduces support for retrieving and validating user info from Okta and ensures consistency with the project's existing OAuth providers.

Summary by CodeRabbit

  • New Features

    • Added Okta as a new OAuth provider option.
    • Dashboard auth settings let you enter an Okta domain when choosing Okta.
    • Okta integration retrieves user info and validates access tokens automatically.
  • Tests

    • Backend tests updated to include "okta" in allowed OAuth provider values.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Dec 3, 2025

@kashish00208 is attempting to deploy a commit to the Stack Auth Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 3, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds Okta OAuth support: new OktaProvider implementation, backend provider registry updated to create Okta providers with oktaDomain, frontend form/UI updated to capture oktaDomain, and a test snapshot updated to include okta in allowed provider types.

Changes

Cohort / File(s) Summary
Backend: provider registry & creation
apps/backend/src/oauth/index.tsx
Registers OktaProvider in the providers mapping and passes oktaDomain when creating non-shared providers.
Backend: Okta provider implementation
apps/backend/src/oauth/providers/okta.tsx
New OktaProvider class (extends OAuthBaseProvider) with static create, postProcessUserInfo, and checkAccessTokenValidity; constructs Okta endpoints, validates oktaDomain, fetches /v1/userinfo, and validates tokens/user info.
Frontend: provider form & UI
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
Adds oktaDomain to form schema, default values, submission payload, and conditional input rendering for Okta provider.
Tests: expected messages
apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.ts
Updated test snapshot to include okta in the allowed OAuth provider types error message.

Sequence Diagram

sequenceDiagram
    actor User
    participant Dashboard as Dashboard UI
    participant Backend as Backend (OAuth)
    participant OktaAPI as Okta API

    User->>Dashboard: Configure Okta provider (clientId, clientSecret, oktaDomain)
    Dashboard->>Backend: POST provider config (includes oktaDomain)
    Backend->>Backend: Create OktaProvider (validate oktaDomain, set endpoints)

    Note over User,OktaAPI: OAuth login flow
    User->>Backend: Initiate OAuth (redirect)
    Backend->>OktaAPI: Redirect user to Okta auth endpoint
    OktaAPI->>User: Authorization grant (code)
    User->>Backend: Callback with code
    Backend->>OktaAPI: Exchange code at token endpoint
    OktaAPI-->>Backend: Return tokens
    Backend->>OktaAPI: GET /v1/userinfo (access token)
    OktaAPI-->>Backend: User info
    Backend->>Backend: Validate/process user info & tokens
    Backend-->>User: Establish session / complete login
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Inspect apps/backend/src/oauth/providers/okta.tsx for issuer/endpoint construction, error handling, and JWT/userinfo validation.
  • Verify apps/backend/src/oauth/index.tsx provider registration and create-path opt-in for oktaDomain.
  • Check frontend form/schema changes and payload handling in apps/dashboard/.../providers.tsx.
  • Confirm updated test snapshot matches intended error message.

Poem

🐰 I found a domain, neat and bright,
I hopped to Okta through the night,
Tokens fetched and users shown,
New auth doors now proudly grown,
Hooray — another login flight! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add Okta Provider' clearly summarizes the main change—adding Okta OAuth provider support—and is directly related to all modifications in the changeset.
Description check ✅ Passed The description adequately explains the PR purpose (adding OktaProvider implementation and user info retrieval/validation), links to the related issue, and highlights consistency with existing OAuth providers.
Linked Issues check ✅ Passed The implementation fully satisfies issue #19 by adding complete Okta OAuth provider support with user authentication and validation capabilities.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing Okta provider support: provider registration, Okta-specific implementation, dashboard UI integration, and test updates.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Dec 3, 2025

Greptile Overview

Greptile Summary

This PR adds Okta OAuth provider support to Stack Auth, following the existing provider pattern. However, it contains critical bugs that will prevent the feature from working.

Key Changes

  • Added new OktaProvider class with OpenID Connect integration
  • Registered Okta in the provider registry and dashboard UI
  • Added oktaDomain configuration field for custom Okta instances
  • Updated test snapshots to include Okta in provider list

Critical Issues Found

  • Parameter name mismatch in okta.tsx:21,23 - expects okta_issuer but receives oktaDomain from the caller, causing immediate runtime failure
  • Case sensitivity bug in dashboard - checks for 'Okta' (capitalized) but provider key is 'okta' (lowercase), so the domain input field will never appear
  • Multiple formatting inconsistencies (missing spaces after colons)

Impact

The Okta provider cannot be successfully configured or used until the parameter naming and case sensitivity issues are fixed.

Confidence Score: 0/5

  • This PR has critical bugs that will cause runtime failures and prevent the feature from working
  • Score reflects two critical logical errors: (1) parameter name mismatch between okta_issuer and oktaDomain will cause undefined value errors when creating the provider, (2) case sensitivity mismatch ('Okta' vs 'okta') prevents UI configuration field from displaying. These are blocking issues that make the feature completely non-functional.
  • Pay close attention to apps/backend/src/oauth/providers/okta.tsx (parameter naming) and apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx (case sensitivity)

Important Files Changed

File Analysis

Filename Score Overview
apps/backend/src/oauth/providers/okta.tsx 1/5 New Okta provider implementation with critical parameter name mismatch that will cause runtime failure
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx 1/5 Adds Okta UI configuration with case mismatch bug that prevents domain field from showing, plus formatting issues

Sequence Diagram

sequenceDiagram
    participant User
    participant Dashboard
    participant Backend
    participant OktaProvider
    participant Okta

    User->>Dashboard: Configure Okta OAuth
    Dashboard->>Dashboard: Input clientId, clientSecret, oktaDomain
    Dashboard->>Backend: Save provider config
    
    User->>Backend: Initiate OAuth flow
    Backend->>OktaProvider: getAuthorizationUrl()
    OktaProvider->>Backend: Return authorization URL
    Backend->>User: Redirect to Okta
    
    User->>Okta: Authenticate
    Okta->>Backend: OAuth callback with code
    Backend->>OktaProvider: getCallback(code)
    OktaProvider->>Okta: Exchange code for tokens
    Okta->>OktaProvider: Return access token
    OktaProvider->>Okta: GET /v1/userinfo
    Okta->>OktaProvider: Return user profile
    OktaProvider->>Backend: Return validated user info
    Backend->>User: Authentication complete
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

4 files reviewed, 10 comments

Edit Code Review Agent Settings | Greptile

static async create(options: {
clientId: string;
clientSecret: string;
okta_issuer: string;
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: parameter name mismatch - receives oktaDomain from oauth/index.tsx:83 but expects okta_issuer

Suggested change
okta_issuer: string;
oktaDomain: string;
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/backend/src/oauth/providers/okta.tsx
Line: 21:21

Comment:
**logic:** parameter name mismatch - receives `oktaDomain` from `oauth/index.tsx:83` but expects `okta_issuer`

```suggestion
    oktaDomain: string;
```

How can I resolve this? If you propose a fix, please make it concise.

clientSecret: string;
okta_issuer: string;
}) {
const oktaDomain = options.okta_issuer;
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: reading from wrong parameter name - should be options.oktaDomain

Suggested change
const oktaDomain = options.okta_issuer;
const oktaDomain = options.oktaDomain;
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/backend/src/oauth/providers/okta.tsx
Line: 23:23

Comment:
**logic:** reading from wrong parameter name - should be `options.oktaDomain`

```suggestion
    const  oktaDomain  = options.oktaDomain;
```

How can I resolve this? If you propose a fix, please make it concise.

/>
)}

{props.id === 'Okta' && (
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: case mismatch - should be 'okta' (lowercase) to match the provider key in toTitle function and backend

Suggested change
{props.id === 'Okta' && (
{props.id === 'okta' && (
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
Line: 174:174

Comment:
**logic:** case mismatch - should be `'okta'` (lowercase) to match the provider key in `toTitle` function and backend

```suggestion
              {props.id === 'okta' && (
```

How can I resolve this? If you propose a fix, please make it concise.

linkedin: LinkedInProvider,
x: XProvider,
twitch: TwitchProvider,
okta:OktaProvider,
Copy link
Contributor

Choose a reason for hiding this comment

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

style: missing space after colon

Suggested change
okta:OktaProvider,
okta: OktaProvider,
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/backend/src/oauth/index.tsx
Line: 35:35

Comment:
**style:** missing space after colon

```suggestion
  okta: OktaProvider,
```

How can I resolve this? If you propose a fix, please make it concise.

clientSecret: provider.clientSecret || throwErr("Client secret is required for standard providers"),
facebookConfigId: provider.facebookConfigId,
microsoftTenantId: provider.microsoftTenantId,
oktaDomain:provider.oktaDomain,
Copy link
Contributor

Choose a reason for hiding this comment

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

style: missing space after colon

Suggested change
oktaDomain:provider.oktaDomain,
oktaDomain: provider.oktaDomain,
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/backend/src/oauth/index.tsx
Line: 83:83

Comment:
**style:** missing space after colon

```suggestion
      oktaDomain: provider.oktaDomain,
```

How can I resolve this? If you propose a fix, please make it concise.

linkedin: "LinkedIn",
twitch: "Twitch",
x: "X",
okta:"Okta"
Copy link
Contributor

Choose a reason for hiding this comment

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

style: missing space after colon

Suggested change
okta:"Okta"
okta: "Okta"
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
Line: 47:47

Comment:
**style:** missing space after colon

```suggestion
    okta: "Okta"
```

How can I resolve this? If you propose a fix, please make it concise.

}),
facebookConfigId: yupString().optional(),
microsoftTenantId: yupString().optional(),
oktaDomain:yupString().optional()
Copy link
Contributor

Choose a reason for hiding this comment

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

style: missing space after colon

Suggested change
oktaDomain:yupString().optional()
oktaDomain: yupString().optional()
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
Line: 67:67

Comment:
**style:** missing space after colon

```suggestion
  oktaDomain: yupString().optional()
```

How can I resolve this? If you propose a fix, please make it concise.

clientSecret: (props.provider as any)?.clientSecret ?? "",
facebookConfigId: (props.provider as any)?.facebookConfigId ?? "",
microsoftTenantId: (props.provider as any)?.microsoftTenantId ?? "",
oktaDomain:(props.provider as any)?.oktaDomain??"",
Copy link
Contributor

Choose a reason for hiding this comment

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

style: missing spaces after colons

Suggested change
oktaDomain:(props.provider as any)?.oktaDomain??"",
oktaDomain: (props.provider as any)?.oktaDomain ?? "",
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
Line: 80:80

Comment:
**style:** missing spaces after colons

```suggestion
    oktaDomain: (props.provider as any)?.oktaDomain ?? "",
```

How can I resolve this? If you propose a fix, please make it concise.

clientSecret: values.clientSecret || "",
facebookConfigId: values.facebookConfigId,
microsoftTenantId: values.microsoftTenantId,
oktaDomain:values.oktaDomain,
Copy link
Contributor

Choose a reason for hiding this comment

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

style: missing space after colon

Suggested change
oktaDomain:values.oktaDomain,
oktaDomain: values.oktaDomain,
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
Line: 94:94

Comment:
**style:** missing space after colon

```suggestion
        oktaDomain: values.oktaDomain,
```

How can I resolve this? If you propose a fix, please make it concise.

NiceResponse {
"status": 400,
"body": "auth.oauth.providers.invalid.type must be one of the following values: google, github, microsoft, spotify, facebook, discord, gitlab, bitbucket, linkedin, apple, x, twitch",
"body": "auth.oauth.providers.invalid.type must be one of the following values: google, github, microsoft, spotify, facebook, discord, gitlab, bitbucket, linkedin, apple, x, twitch,okta",
Copy link
Contributor

Choose a reason for hiding this comment

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

style: missing space after comma

Suggested change
"body": "auth.oauth.providers.invalid.type must be one of the following values: google, github, microsoft, spotify, facebook, discord, gitlab, bitbucket, linkedin, apple, x, twitch,okta",
"body": "auth.oauth.providers.invalid.type must be one of the following values: google, github, microsoft, spotify, facebook, discord, gitlab, bitbucket, linkedin, apple, x, twitch, okta",
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.ts
Line: 378:378

Comment:
**style:** missing space after comma

```suggestion
      "body": "auth.oauth.providers.invalid.type must be one of the following values: google, github, microsoft, spotify, facebook, discord, gitlab, bitbucket, linkedin, apple, x, twitch, okta",
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
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

🧹 Nitpick comments (1)
apps/backend/src/oauth/providers/okta.tsx (1)

9-16: Fix formatting issues.

Minor formatting inconsistencies:

  • Line 9: Extra space before the colon in oktaDomain : string
  • Line 15: Missing semicolon at the end

Apply this diff:

-  private oktaDomain : string;
+  private oktaDomain: string;
   private constructor(
     oktaDomain: string,
     ...args: ConstructorParameters<typeof OAuthBaseProvider>
   ) {
     super(...args);
-    this.oktaDomain = oktaDomain
+    this.oktaDomain = oktaDomain;
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e8e78cf and 453dc86.

📒 Files selected for processing (4)
  • apps/backend/src/oauth/index.tsx (3 hunks)
  • apps/backend/src/oauth/providers/okta.tsx (1 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx (5 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: For blocking alerts and errors, never use toast, as they are easily missed by the user. Instead, use alerts
Keep hover/click transitions snappy and fast. Don't delay the action with a pre-transition; apply transitions after the action instead
NEVER try-catch-all, NEVER void a promise, and NEVER .catch(console.error). Use runAsynchronously or runAsynchronouslyWithAlert instead for asynchronous error handling
When creating hover transitions, avoid hover-enter transitions and just use hover-exit transitions (e.g., transition-colors hover:transition-none)
Use ES6 maps instead of records wherever possible

Files:

  • apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.ts
  • apps/backend/src/oauth/index.tsx
  • apps/backend/src/oauth/providers/okta.tsx
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

When writing tests, prefer .toMatchInlineSnapshot over other selectors, if possible

Files:

  • apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.ts
apps/{backend,dashboard}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

NEVER use Next.js dynamic functions if you can avoid them. Instead, prefer using a client component and prefer usePathname instead of await params

Files:

  • apps/backend/src/oauth/index.tsx
  • apps/backend/src/oauth/providers/okta.tsx
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
🧠 Learnings (1)
📚 Learning: 2025-12-03T07:19:44.416Z
Learnt from: madster456
Repo: stack-auth/stack-auth PR: 1040
File: packages/stack-shared/src/interface/crud/oauth-providers.ts:62-87
Timestamp: 2025-12-03T07:19:44.416Z
Learning: In packages/stack-shared/src/interface/crud/oauth-providers.ts and similar CRUD files, the tag "Oauth" (not "OAuth") is the correct capitalization format as it's used by the documentation generation system and follows OpenAPI conventions.

Applied to files:

  • apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.ts
  • apps/backend/src/oauth/index.tsx
  • apps/backend/src/oauth/providers/okta.tsx
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
🧬 Code graph analysis (3)
apps/backend/src/oauth/index.tsx (1)
apps/backend/src/oauth/providers/okta.tsx (1)
  • OktaProvider (8-79)
apps/backend/src/oauth/providers/okta.tsx (5)
packages/stack-shared/src/utils/errors.tsx (1)
  • StackAssertionError (69-85)
packages/stack-shared/src/utils/env.tsx (1)
  • getEnvVariable (16-58)
apps/backend/src/oauth/providers/base.tsx (1)
  • TokenSet (7-12)
apps/backend/src/oauth/utils.tsx (2)
  • OAuthUserInfo (4-4)
  • validateUserInfo (14-18)
packages/stack-shared/src/utils/jwt.tsx (1)
  • getJwtInfo (23-36)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx (2)
packages/stack-shared/src/schema-fields.ts (1)
  • yupString (187-190)
apps/dashboard/src/components/form-fields.tsx (1)
  • InputField (64-102)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Vercel Agent Review
🔇 Additional comments (7)
apps/backend/src/oauth/index.tsx (3)

17-17: LGTM!

The import is correctly added.


35-35: LGTM!

The provider is correctly registered in the mapping.


83-83: Critical: Parameter name mismatch will cause runtime error.

This code passes oktaDomain to the provider, but OktaProvider.create() in apps/backend/src/oauth/providers/okta.tsx (line 21) expects a parameter named okta_issuer, not oktaDomain. This mismatch will cause the Okta domain to be undefined at runtime, leading to invalid URLs and failed authentication.

The fix should be applied in apps/backend/src/oauth/providers/okta.tsx to rename the parameter from okta_issuer to oktaDomain for consistency with the rest of the codebase.

⛔ Skipped due to learnings
Learnt from: madster456
Repo: stack-auth/stack-auth PR: 1040
File: packages/stack-shared/src/interface/crud/oauth-providers.ts:62-87
Timestamp: 2025-12-03T07:19:44.416Z
Learning: In packages/stack-shared/src/interface/crud/oauth-providers.ts and similar CRUD files, the tag "Oauth" (not "OAuth") is the correct capitalization format as it's used by the documentation generation system and follows OpenAPI conventions.
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx (4)

47-47: LGTM!

Okta correctly added to the title mapping.


67-67: LGTM!

The oktaDomain field is correctly added to the form schema as optional.


80-80: LGTM!

The oktaDomain default value is correctly initialized.


94-94: LGTM!

The oktaDomain is correctly included in the submission payload for standard providers.

Comment on lines +174 to +181
{props.id === 'Okta' && (
<InputField
control={form.control}
name="oktaDomain"
label="Okta Domain (required if you are using Okta)"
placeholder="oktaDomain"
/>
)}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Case mismatch prevents Okta domain field from rendering.

The condition checks props.id === 'Okta' (capitalized), but provider IDs are lowercase throughout the codebase. Looking at line 47, the toTitle mapping uses lowercase keys (okta: "Okta"). The similar checks for Facebook (line 156) and Microsoft (line 165) both use lowercase IDs. This condition will always be false, preventing the Okta domain input field from ever being displayed, which breaks the Okta configuration UI.

Apply this diff:

-              {props.id === 'Okta' && (
+              {props.id === 'okta' && (
                <InputField
                  control={form.control}
                  name="oktaDomain"
                  label="Okta Domain (required if you are using Okta)"
                  placeholder="oktaDomain"
                />
              )}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{props.id === 'Okta' && (
<InputField
control={form.control}
name="oktaDomain"
label="Okta Domain (required if you are using Okta)"
placeholder="oktaDomain"
/>
)}
{props.id === 'okta' && (
<InputField
control={form.control}
name="oktaDomain"
label="Okta Domain (required if you are using Okta)"
placeholder="oktaDomain"
/>
)}
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
around lines 174 to 181, the conditional rendering check uses props.id ===
'Okta' (capitalized) which never matches the lowercase provider IDs used
elsewhere; change the comparison to props.id === 'okta' to match the existing id
keys (consistent with the toTitle mapping and other provider checks) so the Okta
Domain InputField is rendered correctly.

/>
)}

{props.id === 'Okta' && (
Copy link

Choose a reason for hiding this comment

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

Suggested change
{props.id === 'Okta' && (
{props.id === 'okta' && (

The condition checks for props.id === 'Okta' (capitalized), but the provider ID throughout the codebase is lowercase 'okta'. This means the Okta domain input field will never be displayed in the UI.

View Details

Analysis

Okta domain input field never renders due to incorrect provider ID case

What fails: The Okta domain input field is never displayed in the OAuth provider configuration dialog, preventing users from entering the required Okta domain when setting up Okta OAuth authentication.

How to reproduce:

  1. Navigate to the dashboard OAuth provider settings for Okta
  2. Enable Okta OAuth and attempt to configure it with custom credentials (not shared keys)
  3. Observe that the "Okta Domain" input field is missing from the form

Root cause: The condition at line 174 in apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx checks props.id === 'Okta' (capitalized), but the provider ID throughout the codebase is lowercase 'okta' (defined in apps/backend/src/oauth/index.tsx line 35 as okta:OktaProvider, and used in the toTitle mapping at line 47 as okta:"Okta"). This string comparison never matches, so the field is never rendered.

Expected behavior: The Okta domain input field should be displayed when configuring Okta OAuth, consistent with how the facebook and microsoft provider conditions work (lines 155 and 164, which use lowercase IDs).

Fix: Changed line 174 from props.id === 'Okta' to props.id === 'okta' to match the actual provider ID used throughout the codebase.

clientSecret: provider.clientSecret || throwErr("Client secret is required for standard providers"),
facebookConfigId: provider.facebookConfigId,
microsoftTenantId: provider.microsoftTenantId,
oktaDomain:provider.oktaDomain,
Copy link

Choose a reason for hiding this comment

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

The OktaProvider.create() method expects a parameter named okta_issuer, but the code is passing oktaDomain. This will cause the provider to fail with "Okta domain is required" at runtime.

View Details
📝 Patch Details
diff --git a/apps/backend/src/app/api/latest/integrations/neon/oauth-providers/crud.tsx b/apps/backend/src/app/api/latest/integrations/neon/oauth-providers/crud.tsx
index 858018bc..73498f06 100644
--- a/apps/backend/src/app/api/latest/integrations/neon/oauth-providers/crud.tsx
+++ b/apps/backend/src/app/api/latest/integrations/neon/oauth-providers/crud.tsx
@@ -22,6 +22,7 @@ const oauthProviderReadSchema = yupObject({
   // extra params
   facebook_config_id: schemaFields.oauthFacebookConfigIdSchema.optional(),
   microsoft_tenant_id: schemaFields.oauthMicrosoftTenantIdSchema.optional(),
+  okta_issuer: schemaFields.oauthOktaIssuerSchema.optional(),
 });
 
 const oauthProviderUpdateSchema = yupObject({
@@ -38,6 +39,7 @@ const oauthProviderUpdateSchema = yupObject({
   // extra params
   facebook_config_id: schemaFields.oauthFacebookConfigIdSchema.optional(),
   microsoft_tenant_id: schemaFields.oauthMicrosoftTenantIdSchema.optional(),
+  okta_issuer: schemaFields.oauthOktaIssuerSchema.optional(),
 });
 
 const oauthProviderCreateSchema = oauthProviderUpdateSchema.defined().concat(yupObject({
@@ -77,6 +79,7 @@ function oauthProviderConfigToLegacyConfig(provider: Tenancy['config']['auth']['
     client_secret: provider.clientSecret,
     facebook_config_id: provider.facebookConfigId,
     microsoft_tenant_id: provider.microsoftTenantId,
+    okta_issuer: provider.oktaIssuer,
   } as const;
 }
 
diff --git a/apps/backend/src/lib/config.tsx b/apps/backend/src/lib/config.tsx
index 0838f3d4..d3480cac 100644
--- a/apps/backend/src/lib/config.tsx
+++ b/apps/backend/src/lib/config.tsx
@@ -518,6 +518,7 @@ export const renderedOrganizationConfigToProjectCrud = (renderedConfig: Complete
         client_secret: oauthProvider.clientSecret,
         facebook_config_id: oauthProvider.facebookConfigId,
         microsoft_tenant_id: oauthProvider.microsoftTenantId,
+        okta_issuer: oauthProvider.oktaIssuer,
       } as const) satisfies ProjectsCrud["Admin"]["Read"]['config']['oauth_providers'][number];
     })
     .filter(isTruthy)
diff --git a/apps/backend/src/lib/projects.tsx b/apps/backend/src/lib/projects.tsx
index 713ac097..d698d913 100644
--- a/apps/backend/src/lib/projects.tsx
+++ b/apps/backend/src/lib/projects.tsx
@@ -188,6 +188,7 @@ export async function createOrUpdateProjectWithLegacyConfig(
             clientSecret: provider.client_secret,
             facebookConfigId: provider.facebook_config_id,
             microsoftTenantId: provider.microsoft_tenant_id,
+            oktaIssuer: provider.okta_issuer,
             allowSignIn: true,
             allowConnectedAccounts: true,
           } satisfies CompleteConfig['auth']['oauth']['providers'][string]
diff --git a/apps/backend/src/oauth/index.tsx b/apps/backend/src/oauth/index.tsx
index 616a0a7c..ac20ca53 100644
--- a/apps/backend/src/oauth/index.tsx
+++ b/apps/backend/src/oauth/index.tsx
@@ -80,7 +80,7 @@ export async function getProvider(provider: Tenancy['config']['auth']['oauth']['
       clientSecret: provider.clientSecret || throwErr("Client secret is required for standard providers"),
       facebookConfigId: provider.facebookConfigId,
       microsoftTenantId: provider.microsoftTenantId,
-      oktaDomain:provider.oktaDomain,
+      okta_issuer: provider.oktaIssuer,
     });
   }
 }
diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
index 7e262d36..e2f3afe4 100644
--- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
+++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
@@ -64,7 +64,7 @@ export const providerFormSchema = yupObject({
     }),
   facebookConfigId: yupString().optional(),
   microsoftTenantId: yupString().optional(),
-  oktaDomain:yupString().optional()
+  oktaIssuer:yupString().optional()
 });
 
 export type ProviderFormValues = yup.InferType<typeof providerFormSchema>
@@ -77,7 +77,7 @@ export function ProviderSettingDialog(props: Props & { open: boolean, onClose: (
     clientSecret: (props.provider as any)?.clientSecret ?? "",
     facebookConfigId: (props.provider as any)?.facebookConfigId ?? "",
     microsoftTenantId: (props.provider as any)?.microsoftTenantId ?? "",
-    oktaDomain:(props.provider as any)?.oktaDomain??"",
+    oktaIssuer:(props.provider as any)?.oktaIssuer??"",
   };
 
   const onSubmit = async (values: ProviderFormValues) => {
@@ -91,7 +91,7 @@ export function ProviderSettingDialog(props: Props & { open: boolean, onClose: (
         clientSecret: values.clientSecret || "",
         facebookConfigId: values.facebookConfigId,
         microsoftTenantId: values.microsoftTenantId,
-        oktaDomain:values.oktaDomain,
+        oktaIssuer:values.oktaIssuer,
       });
     }
   };
@@ -171,12 +171,12 @@ export function ProviderSettingDialog(props: Props & { open: boolean, onClose: (
                 />
               )}
 
-              {props.id === 'Okta' && (
+              {props.id === 'okta' && (
                 <InputField
                   control={form.control}
-                  name="oktaDomain"
-                  label="Okta Domain (required if you are using Okta)"
-                  placeholder="oktaDomain"
+                  name="oktaIssuer"
+                  label="Okta Issuer URL (required if you are using Okta)"
+                  placeholder="https://your-domain.okta.com"
                 />
               )}
             </>
diff --git a/packages/stack-shared/src/config/schema-fuzzer.test.ts b/packages/stack-shared/src/config/schema-fuzzer.test.ts
index 36475954..dded169c 100644
--- a/packages/stack-shared/src/config/schema-fuzzer.test.ts
+++ b/packages/stack-shared/src/config/schema-fuzzer.test.ts
@@ -180,6 +180,7 @@ const environmentSchemaFuzzerConfig = [{
         clientSecret: ["some-client-secret"],
         facebookConfigId: ["some-facebook-config-id"],
         microsoftTenantId: ["some-microsoft-tenant-id"],
+        oktaIssuer: ["https://example.okta.com"],
       }]]))] as const,
     }],
   }],
diff --git a/packages/stack-shared/src/config/schema.ts b/packages/stack-shared/src/config/schema.ts
index 8835d595..73a55947 100644
--- a/packages/stack-shared/src/config/schema.ts
+++ b/packages/stack-shared/src/config/schema.ts
@@ -223,6 +223,7 @@ export const environmentConfigSchema = branchConfigSchema.concat(yupObject({
           clientSecret: schemaFields.oauthClientSecretSchema.optional(),
           facebookConfigId: schemaFields.oauthFacebookConfigIdSchema.optional(),
           microsoftTenantId: schemaFields.oauthMicrosoftTenantIdSchema.optional(),
+          oktaIssuer: schemaFields.oauthOktaIssuerSchema.optional(),
           allowSignIn: yupBoolean().optional(),
           allowConnectedAccounts: yupBoolean().optional(),
         }),
@@ -507,6 +508,7 @@ const organizationConfigDefaults = {
         clientSecret: undefined,
         facebookConfigId: undefined,
         microsoftTenantId: undefined,
+        oktaIssuer: undefined,
       }),
     },
   },
diff --git a/packages/stack-shared/src/interface/crud/projects.ts b/packages/stack-shared/src/interface/crud/projects.ts
index b37713c2..45264e2e 100644
--- a/packages/stack-shared/src/interface/crud/projects.ts
+++ b/packages/stack-shared/src/interface/crud/projects.ts
@@ -22,6 +22,7 @@ const oauthProviderReadSchema = yupObject({
   // extra params
   facebook_config_id: schemaFields.oauthFacebookConfigIdSchema.optional(),
   microsoft_tenant_id: schemaFields.oauthMicrosoftTenantIdSchema.optional(),
+  okta_issuer: schemaFields.oauthOktaIssuerSchema.optional(),
 });
 
 const oauthProviderWriteSchema = oauthProviderReadSchema.omit(['provider_config_id']);
diff --git a/packages/stack-shared/src/schema-fields.ts b/packages/stack-shared/src/schema-fields.ts
index ca6f9c22..1e3e682f 100644
--- a/packages/stack-shared/src/schema-fields.ts
+++ b/packages/stack-shared/src/schema-fields.ts
@@ -527,6 +527,7 @@ export const oauthClientIdSchema = yupString().meta({ openapiField: { descriptio
 export const oauthClientSecretSchema = yupString().meta({ openapiField: { description: 'OAuth client secret. Needs to be specified when using type="standard"', exampleValue: 'google-oauth-client-secret' } });
 export const oauthFacebookConfigIdSchema = yupString().meta({ openapiField: { description: 'The configuration id for Facebook business login (for things like ads and marketing). This is only required if you are using the standard OAuth with Facebook and you are using Facebook business login.' } });
 export const oauthMicrosoftTenantIdSchema = yupString().meta({ openapiField: { description: 'The Microsoft tenant id for Microsoft directory. This is only required if you are using the standard OAuth with Microsoft and you have an Azure AD tenant.' } });
+export const oauthOktaIssuerSchema = yupString().meta({ openapiField: { description: 'The Okta issuer URL. This is required if you are using the standard OAuth with Okta.' } });
 export const oauthAccountMergeStrategySchema = yupString().oneOf(['link_method', 'raise_error', 'allow_duplicates']).meta({ openapiField: { description: 'Determines how to handle OAuth logins that match an existing user by email. `link_method` adds the OAuth method to the existing user. `raise_error` rejects the login with an error. `allow_duplicates` creates a new user.', exampleValue: 'link_method' } });
 // Project email config
 export const emailTypeSchema = yupString().oneOf(['shared', 'standard']).meta({ openapiField: { description: 'Email provider type, one of shared, standard. "shared" uses Stack shared email provider and it is only meant for development. "standard" uses your own email server and will have your email address as the sender.', exampleValue: 'standard' } });

Analysis

Okta OAuth Provider Configuration Missing Required Field

What fails: OktaProvider.create() expects an okta_issuer parameter, but the configuration schema and getProvider() function in apps/backend/src/oauth/index.tsx line 83 had no mechanism to pass this required parameter, causing Okta OAuth provider initialization to fail with "Okta domain is required" error at runtime.

How to reproduce:

  1. Configure an Okta OAuth provider with type: 'okta' in project config
  2. Set clientId, clientSecret, and the Okta issuer URL
  3. Attempt to use Okta authentication in the application
  4. Runtime error: StackAssertionError("Okta domain is required ")

Result: The Okta provider fails initialization because options.okta_issuer is undefined, causing the validation check at apps/backend/src/oauth/providers/okta.tsx:25 to throw an error.

Expected: Okta provider should receive the configured issuer URL and properly initialize the OAuth flow.

Fix:

  • Added oktaIssuer field to the OAuth provider configuration schema
  • Added corresponding schema field oauthOktaIssuerSchema in schema-fields.ts
  • Updated getProvider() to pass ok ta_issuer: provider.oktaIssuer to OktaProvider.create()
  • Updated config conversion functions to map between snake_case (okta_issuer) and camelCase (oktaIssuer)
  • Updated CRUD interface and fuzzer tests to include the new field

Copy link
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: 1

♻️ Duplicate comments (3)
apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.ts (1)

378-378: Add space after comma before "okta" for consistency.

The provider list should have consistent spacing. All other providers in the list have a space after the comma (, provider), but "okta" is missing this space (,okta).

Apply this diff:

-      "body": "auth.oauth.providers.invalid.type must be one of the following values: google, github, microsoft, spotify, facebook, discord, gitlab, bitbucket, linkedin, apple, x, twitch,okta",
+      "body": "auth.oauth.providers.invalid.type must be one of the following values: google, github, microsoft, spotify, facebook, discord, gitlab, bitbucket, linkedin, apple, x, twitch, okta",
apps/backend/src/oauth/providers/okta.tsx (1)

18-41: Critical: Missing URL protocols will cause OAuth to fail.

Three OAuth endpoint URLs are missing the https:// protocol prefix:

  • Line 31: authorizationEndpoint
  • Line 32: tokenEndpoint
  • Line 34: jwksUri

If oktaDomain contains only the domain (e.g., dev-123.okta.com), these will create invalid URLs like dev-123.okta.com/v1/authorize instead of https://dev-123.okta.com/v1/authorize, causing OAuth authentication to fail.

Additional minor issues:

  • Line 23: Extra spaces around variable name
  • Line 25: Missing space after if and trailing space in error message
  • Line 40: Unnecessary semicolon after closing parenthesis

Apply this diff:

   static async create(options: {
     clientId: string;
     clientSecret: string;
     oktaDomain: string;
   }) {
-    const  oktaDomain  = options.oktaDomain;
+    const oktaDomain = options.oktaDomain;
 
-    if(!oktaDomain) throw new StackAssertionError("Okta domain is required ")
+    if (!oktaDomain) throw new StackAssertionError("Okta domain is required");
 
     return new OktaProvider(
       oktaDomain,
       ...await OAuthBaseProvider.createConstructorArgs({
         issuer: `https://${oktaDomain}`,
-        authorizationEndpoint: `${oktaDomain}/v1/authorize`,
-        tokenEndpoint: `${oktaDomain}/v1/token`,
+        authorizationEndpoint: `https://${oktaDomain}/v1/authorize`,
+        tokenEndpoint: `https://${oktaDomain}/v1/token`,
         redirectUri: getEnvVariable("OAUTH_REDIRECT_URI")!,
-        jwksUri: `${oktaDomain}/v1/keys`,
+        jwksUri: `https://${oktaDomain}/v1/keys`,
         baseScope: "openid email profile",
         authorizationExtraParams: { response_mode: "form_post" },
         tokenEndpointAuthMethod: "client_secret_basic",
         ...options,
-      }))
-    ;
+      })
+    );
   }
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx (1)

174-181: Critical: Case mismatch prevents Okta domain field from rendering.

Line 174 checks props.id === 'Okta' (capitalized), but provider IDs are lowercase throughout the codebase. This condition will always be false, preventing the Okta domain input field from ever being displayed.

Evidence:

  • Line 156: Facebook uses 'facebook' (lowercase)
  • Line 165: Microsoft uses 'microsoft' (lowercase)
  • Line 47: toTitle mapping key is okta (lowercase)
  • apps/backend/src/oauth/index.tsx line 35: Provider registered as okta (lowercase)

Without this field, users cannot configure Okta OAuth with custom credentials, breaking the Okta provider setup flow.

Apply this diff:

-              {props.id === 'Okta' && (
+              {props.id === 'okta' && (
                 <InputField
                   control={form.control}
                   name="oktaDomain"
                   label="Okta Domain (required if you are using Okta)"
                   placeholder="oktaDomain"
                 />
               )}
🧹 Nitpick comments (2)
apps/backend/src/oauth/providers/okta.tsx (1)

9-15: Fix formatting inconsistencies.

Two minor style issues:

  • Line 9: Extra space before colon in private oktaDomain : string;
  • Line 15: Missing semicolon after assignment

Apply this diff:

-  private oktaDomain : string;
+  private oktaDomain: string;
   private constructor(
     oktaDomain: string,
     ...args: ConstructorParameters<typeof OAuthBaseProvider>
   ) {
     super(...args);
-    this.oktaDomain = oktaDomain
+    this.oktaDomain = oktaDomain;
   }
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx (1)

80-80: Fix spacing for consistency.

Line 80 has formatting inconsistencies:

  • Missing space after colon
  • Missing space before ?? operator

Compare with lines 76-79 which have proper spacing.

Apply this diff:

-    oktaDomain:(props.provider as any)?.oktaDomain?? "",
+    oktaDomain: (props.provider as any)?.oktaDomain ?? "",
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 453dc86 and 8190ed8.

📒 Files selected for processing (4)
  • apps/backend/src/oauth/index.tsx (3 hunks)
  • apps/backend/src/oauth/providers/okta.tsx (1 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx (5 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: For blocking alerts and errors, never use toast, as they are easily missed by the user. Instead, use alerts
Keep hover/click transitions snappy and fast. Don't delay the action with a pre-transition; apply transitions after the action instead
NEVER try-catch-all, NEVER void a promise, and NEVER .catch(console.error). Use runAsynchronously or runAsynchronouslyWithAlert instead for asynchronous error handling
When creating hover transitions, avoid hover-enter transitions and just use hover-exit transitions (e.g., transition-colors hover:transition-none)
Use ES6 maps instead of records wherever possible

Files:

  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
  • apps/backend/src/oauth/index.tsx
  • apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.ts
  • apps/backend/src/oauth/providers/okta.tsx
apps/{backend,dashboard}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

NEVER use Next.js dynamic functions if you can avoid them. Instead, prefer using a client component and prefer usePathname instead of await params

Files:

  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
  • apps/backend/src/oauth/index.tsx
  • apps/backend/src/oauth/providers/okta.tsx
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

When writing tests, prefer .toMatchInlineSnapshot over other selectors, if possible

Files:

  • apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.ts
🧠 Learnings (1)
📚 Learning: 2025-12-03T07:19:44.416Z
Learnt from: madster456
Repo: stack-auth/stack-auth PR: 1040
File: packages/stack-shared/src/interface/crud/oauth-providers.ts:62-87
Timestamp: 2025-12-03T07:19:44.416Z
Learning: In packages/stack-shared/src/interface/crud/oauth-providers.ts and similar CRUD files, the tag "Oauth" (not "OAuth") is the correct capitalization format as it's used by the documentation generation system and follows OpenAPI conventions.

Applied to files:

  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
  • apps/backend/src/oauth/index.tsx
  • apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.ts
  • apps/backend/src/oauth/providers/okta.tsx
🧬 Code graph analysis (3)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx (2)
packages/stack-shared/src/schema-fields.ts (1)
  • yupString (187-190)
apps/dashboard/src/components/form-fields.tsx (1)
  • InputField (64-102)
apps/backend/src/oauth/index.tsx (1)
apps/backend/src/oauth/providers/okta.tsx (1)
  • OktaProvider (8-79)
apps/backend/src/oauth/providers/okta.tsx (5)
packages/stack-shared/src/utils/errors.tsx (1)
  • StackAssertionError (69-85)
packages/stack-shared/src/utils/env.tsx (1)
  • getEnvVariable (16-58)
apps/backend/src/oauth/providers/base.tsx (1)
  • TokenSet (7-12)
apps/backend/src/oauth/utils.tsx (2)
  • OAuthUserInfo (4-4)
  • validateUserInfo (14-18)
packages/stack-shared/src/utils/jwt.tsx (1)
  • getJwtInfo (23-36)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Vercel Agent Review
🔇 Additional comments (7)
apps/backend/src/oauth/providers/okta.tsx (2)

43-70: LGTM! User info fetching is correctly implemented.

The method properly:

  • Constructs the userinfo endpoint URL with https:// protocol
  • Handles authentication with Bearer token
  • Provides detailed error information including status, body, and JWT info
  • Maps Okta user fields to the standard OAuthUserInfo format
  • Validates the result with validateUserInfo

71-79: LGTM! Access token validation is correctly implemented.

The method properly constructs the userinfo endpoint URL with https:// protocol and validates the token by checking the response status.

apps/backend/src/oauth/index.tsx (3)

17-17: LGTM! Import statement is correct.

The OktaProvider import follows the same pattern as other provider imports.


35-35: LGTM! Provider registration is correct.

The okta provider is properly registered in the _providers mapping with correct formatting.


83-83: Verify that provider.oktaDomain exists in the Tenancy config schema.

The code passes oktaDomain: provider.oktaDomain to OktaProvider.create(), which should match the expected parameter name in the OktaProvider.create() signature. Ensure this field is defined in your provider configuration schema.

apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx (2)

67-67: LGTM! Schema field is correctly defined.

The oktaDomain field follows the same pattern as other optional provider-specific fields (facebookConfigId, microsoftTenantId).


94-94: LGTM! Submission payload correctly includes oktaDomain.

The field is properly added to the provider update payload with correct formatting.

"status": 400,
"body": "auth.oauth.providers.invalid.type must be one of the following values: google, github, microsoft, spotify, facebook, discord, gitlab, bitbucket, linkedin, apple, x, twitch",
"headers": Headers { <some fields may have been hidden> },
"body": "auth.oauth.providers.invalid.type must be one of the following values: google, github, microsoft, spotify, facebook, discord, gitlab, bitbucket, linkedin, apple, x, twitch, okta", "headers": Headers { <some fields may have been hidden> },
Copy link

@vercel vercel bot Dec 3, 2025

Choose a reason for hiding this comment

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

Suggested change
"body": "auth.oauth.providers.invalid.type must be one of the following values: google, github, microsoft, spotify, facebook, discord, gitlab, bitbucket, linkedin, apple, x, twitch, okta", "headers": Headers { <some fields may have been hidden> },
"body": "auth.oauth.providers.invalid.type must be one of the following values: google, github, microsoft, spotify, facebook, discord, gitlab, bitbucket, linkedin, apple, x, twitch, okta",
"headers": Headers { <some fields may have been hidden> },

The snapshot test has a formatting error where the "headers" property is concatenated on the same line as the "body" property with incorrect spacing, breaking the snapshot format.

View Details

Analysis

Snapshot formatting inconsistency in config.test.ts

What fails: Inline snapshot on line 378 of config.test.ts has "headers" property concatenated on the same line as "body" property with extra spaces, breaking snapshot format consistency

How to reproduce: Compare snapshot formatting across the file - line 342 and 408 have correct formatting with "headers" on separate lines, while line 378 has incorrect formatting with extra spaces concatenating properties on one line

Expected behavior: All snapshot properties should be on separate lines with consistent indentation, matching the format in lines 342 and 408

Result before fix: Line 378 contained:

      "body": "...long string...",      "headers": Headers { <some fields may have been hidden> },

Result after fix: Line 378 now properly formatted as:

      "body": "...long string...",
      "headers": Headers { <some fields may have been hidden> },

Copy link
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: 0

♻️ Duplicate comments (2)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx (2)

80-80: Minor: fix spacing around oktaDomain default for readability.

The logic is fine, but spacing is inconsistent with neighboring fields; it hurts readability a bit.

-    oktaDomain:(props.provider as any)?.oktaDomain?? "",
+    oktaDomain: (props.provider as any)?.oktaDomain ?? "",

174-181: Fix provider ID case so the Okta domain field actually renders.

props.id appears to be lowercase for all providers (see toTitle keys and other checks like 'facebook' and 'microsoft'). Using 'Okta' here means this branch never runs, so the Okta domain input is never shown.

-              {props.id === 'Okta' && (
+              {props.id === 'okta' && (
                 <InputField
                   control={form.control}
                   name="oktaDomain"
                   label="Okta Domain (required if you are using Okta)"
                   placeholder="oktaDomain"
                 />
               )}
🧹 Nitpick comments (1)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx (1)

67-67: Schema extension for oktaDomain aligns with other provider-specific fields.

Adding oktaDomain as an optional string follows the same pattern as facebookConfigId and microsoftTenantId, so it integrates cleanly into the existing validation schema. If oktaDomain must be strictly required for non‑shared Okta configs, you could later tighten this with a provider‑specific validation rule.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8190ed8 and 882f106.

📒 Files selected for processing (3)
  • apps/backend/src/oauth/providers/okta.tsx (1 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx (5 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.ts
  • apps/backend/src/oauth/providers/okta.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: For blocking alerts and errors, never use toast, as they are easily missed by the user. Instead, use alerts
Keep hover/click transitions snappy and fast. Don't delay the action with a pre-transition; apply transitions after the action instead
NEVER try-catch-all, NEVER void a promise, and NEVER .catch(console.error). Use runAsynchronously or runAsynchronouslyWithAlert instead for asynchronous error handling
When creating hover transitions, avoid hover-enter transitions and just use hover-exit transitions (e.g., transition-colors hover:transition-none)
Use ES6 maps instead of records wherever possible

Files:

  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
apps/{backend,dashboard}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

NEVER use Next.js dynamic functions if you can avoid them. Instead, prefer using a client component and prefer usePathname instead of await params

Files:

  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
🧠 Learnings (1)
📚 Learning: 2025-12-03T07:19:44.416Z
Learnt from: madster456
Repo: stack-auth/stack-auth PR: 1040
File: packages/stack-shared/src/interface/crud/oauth-providers.ts:62-87
Timestamp: 2025-12-03T07:19:44.416Z
Learning: In packages/stack-shared/src/interface/crud/oauth-providers.ts and similar CRUD files, the tag "Oauth" (not "OAuth") is the correct capitalization format as it's used by the documentation generation system and follows OpenAPI conventions.

Applied to files:

  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Vercel Agent Review
🔇 Additional comments (2)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx (2)

47-47: Okta title mapping looks correct and consistent.

The okta: "Okta" entry matches the casing pattern used for other providers in toTitle, so the display name will be consistent in the UI.


94-94: Forwarding oktaDomain in the update payload is consistent with other fields.

Including oktaDomain alongside facebookConfigId and microsoftTenantId ensures the Okta-specific configuration is persisted with the rest of the provider settings.

Copy link

@vercel vercel bot left a comment

Choose a reason for hiding this comment

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

Additional Suggestion:

The standardProviders array was not updated to include "okta", which will cause the Okta provider to not be recognized as a valid provider type throughout the system.

View Details
📝 Patch Details
diff --git a/packages/stack-shared/src/utils/oauth.tsx b/packages/stack-shared/src/utils/oauth.tsx
index e8972bfe..09d9ceab 100644
--- a/packages/stack-shared/src/utils/oauth.tsx
+++ b/packages/stack-shared/src/utils/oauth.tsx
@@ -1,4 +1,4 @@
-export const standardProviders = ["google", "github", "microsoft", "spotify", "facebook", "discord", "gitlab", "bitbucket", "linkedin", "apple", "x", "twitch"] as const;
+export const standardProviders = ["google", "github", "microsoft", "spotify", "facebook", "discord", "gitlab", "bitbucket", "linkedin", "apple", "x", "twitch", "okta"] as const;
 // No more shared providers should be added except for special cases
 export const sharedProviders = ["google", "github", "microsoft", "spotify"] as const;
 export const allProviders = standardProviders;

Analysis

Missing Okta provider in standardProviders array causes validation failure

What fails: Configuration validation rejects Okta as a valid OAuth provider type even though the Okta provider is fully implemented in the backend, because standardProviders in packages/stack-shared/src/utils/oauth.tsx does not include "okta"

How to reproduce:

  1. Try to configure Okta as an OAuth provider in the application config
  2. The validation will fail with error: "auth.oauth.providers.{name}.type must be one of the following values: google, github, microsoft, spotify, facebook, discord, gitlab, bitbucket, linkedin, apple, x, twitch"
  3. The e2e test in apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.ts line 378 expects Okta to be in this list but fails without the fix

Result: Configuration validation incorrectly rejects Okta provider configuration. Backend type validation in schema.ts line 138 and 220 uses allProviders which is derived from standardProviders, causing the rejection.

Expected: Okta should be accepted as a valid provider type. The OktaProvider class exists in apps/backend/src/oauth/providers/okta.tsx, is registered in the _providers map at apps/backend/src/oauth/index.tsx line 35, and can be instantiated with the required oktaDomain configuration parameter.

Fix: Added "okta" to the standardProviders array in packages/stack-shared/src/utils/oauth.tsx

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.

Support okta 😃

2 participants