-
Notifications
You must be signed in to change notification settings - Fork 484
feat : add Okta Provider #1043
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
feat : add Okta Provider #1043
Conversation
|
@kashish00208 is attempting to deploy a commit to the Stack Auth Team on Vercel. A member of the Team first needs to authorize it. |
|
|
|
Note Other AI code review bot(s) detectedCodeRabbit 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. WalkthroughAdds 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
Sequence DiagramsequenceDiagram
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
Greptile OverviewGreptile SummaryThis 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
Critical Issues Found
ImpactThe Okta provider cannot be successfully configured or used until the parameter naming and case sensitivity issues are fixed. Confidence Score: 0/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
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
|
There was a problem hiding this 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
| static async create(options: { | ||
| clientId: string; | ||
| clientSecret: string; | ||
| okta_issuer: string; |
There was a problem hiding this comment.
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
| 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; |
There was a problem hiding this comment.
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
| 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' && ( |
There was a problem hiding this comment.
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
| {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.
apps/backend/src/oauth/index.tsx
Outdated
| linkedin: LinkedInProvider, | ||
| x: XProvider, | ||
| twitch: TwitchProvider, | ||
| okta:OktaProvider, |
There was a problem hiding this comment.
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
| 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.
apps/backend/src/oauth/index.tsx
Outdated
| clientSecret: provider.clientSecret || throwErr("Client secret is required for standard providers"), | ||
| facebookConfigId: provider.facebookConfigId, | ||
| microsoftTenantId: provider.microsoftTenantId, | ||
| oktaDomain:provider.oktaDomain, |
There was a problem hiding this comment.
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
| 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" |
There was a problem hiding this comment.
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
| 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() |
There was a problem hiding this comment.
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
| 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??"", |
There was a problem hiding this comment.
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
| 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, |
There was a problem hiding this comment.
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
| 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", |
There was a problem hiding this comment.
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
| "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.There was a problem hiding this 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
📒 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 usetoast, 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). UserunAsynchronouslyorrunAsynchronouslyWithAlertinstead 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.tsapps/backend/src/oauth/index.tsxapps/backend/src/oauth/providers/okta.tsxapps/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
usePathnameinstead ofawait params
Files:
apps/backend/src/oauth/index.tsxapps/backend/src/oauth/providers/okta.tsxapps/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.tsapps/backend/src/oauth/index.tsxapps/backend/src/oauth/providers/okta.tsxapps/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
oktaDomainto the provider, butOktaProvider.create()in apps/backend/src/oauth/providers/okta.tsx (line 21) expects a parameter namedokta_issuer, notoktaDomain. 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_issuertooktaDomainfor 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.
| {props.id === 'Okta' && ( | ||
| <InputField | ||
| control={form.control} | ||
| name="oktaDomain" | ||
| label="Okta Domain (required if you are using Okta)" | ||
| placeholder="oktaDomain" | ||
| /> | ||
| )} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| {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.
apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.ts
Outdated
Show resolved
Hide resolved
| /> | ||
| )} | ||
|
|
||
| {props.id === 'Okta' && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| {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:
- Navigate to the dashboard OAuth provider settings for Okta
- Enable Okta OAuth and attempt to configure it with custom credentials (not shared keys)
- 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.
apps/backend/src/oauth/index.tsx
Outdated
| clientSecret: provider.clientSecret || throwErr("Client secret is required for standard providers"), | ||
| facebookConfigId: provider.facebookConfigId, | ||
| microsoftTenantId: provider.microsoftTenantId, | ||
| oktaDomain:provider.oktaDomain, |
There was a problem hiding this comment.
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:
- Configure an Okta OAuth provider with
type: 'okta'in project config - Set
clientId,clientSecret, and the Okta issuer URL - Attempt to use Okta authentication in the application
- 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
oktaIssuerfield to the OAuth provider configuration schema - Added corresponding schema field
oauthOktaIssuerSchemain schema-fields.ts - Updated
getProvider()to passok ta_issuer: provider.oktaIssuerto 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
There was a problem hiding this 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:
jwksUriIf
oktaDomaincontains only the domain (e.g.,dev-123.okta.com), these will create invalid URLs likedev-123.okta.com/v1/authorizeinstead ofhttps://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
ifand 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
??operatorCompare 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
📒 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 usetoast, 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). UserunAsynchronouslyorrunAsynchronouslyWithAlertinstead 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.tsxapps/backend/src/oauth/index.tsxapps/e2e/tests/backend/endpoints/api/v1/internal/config.test.tsapps/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
usePathnameinstead ofawait params
Files:
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsxapps/backend/src/oauth/index.tsxapps/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.tsxapps/backend/src/oauth/index.tsxapps/e2e/tests/backend/endpoints/api/v1/internal/config.test.tsapps/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 thatprovider.oktaDomainexists in the Tenancy config schema.The code passes
oktaDomain: provider.oktaDomainto 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
oktaDomainfield 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.
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
Outdated
Show resolved
Hide resolved
| "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> }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| "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> },
There was a problem hiding this 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 aroundoktaDomaindefault 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.idappears to be lowercase for all providers (seetoTitlekeys 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 foroktaDomainaligns with other provider-specific fields.Adding
oktaDomainas an optional string follows the same pattern asfacebookConfigIdandmicrosoftTenantId, so it integrates cleanly into the existing validation schema. IfoktaDomainmust 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
📒 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 usetoast, 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). UserunAsynchronouslyorrunAsynchronouslyWithAlertinstead 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
usePathnameinstead ofawait 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 intoTitle, so the display name will be consistent in the UI.
94-94: ForwardingoktaDomainin the update payload is consistent with other fields.Including
oktaDomainalongsidefacebookConfigIdandmicrosoftTenantIdensures the Okta-specific configuration is persisted with the rest of the provider settings.
There was a problem hiding this 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:
- Try to configure Okta as an OAuth provider in the application config
- 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"
- The e2e test in
apps/e2e/tests/backend/endpoints/api/v1/internal/config.test.tsline 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
Closes #19
This PR adds the
OktaProviderimplementation 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
Tests
✏️ Tip: You can customize this high-level summary in your review settings.