From d7819fc83cbdc7fcb07c376265672c5f2b7ac7d9 Mon Sep 17 00:00:00 2001 From: Akshay Date: Thu, 9 Oct 2025 08:07:02 -0700 Subject: [PATCH] feat(auth): add Okta OAuth support and auth configuration enhancements - Add Okta as social authentication provider with OKTA_ISSUER support - Add Google/Microsoft force account selection flags - Respect DISABLE_EMAIL_SIGN_IN and DISABLE_SIGN_UP environment variables - Update OAuth documentation with Okta setup and configuration options - Implement secret tainting for enhanced security --- docs/tips-guides/oauth.md | 31 ++++++++++++++++++++++-- src/components/auth/sign-in.tsx | 9 +++++++ src/components/auth/social-providers.tsx | 11 +++++++++ src/lib/auth/config.ts | 25 +++++++++++++++++++ src/types/authentication.ts | 10 ++++++++ 5 files changed, 84 insertions(+), 2 deletions(-) diff --git a/docs/tips-guides/oauth.md b/docs/tips-guides/oauth.md index a54d4511a..9dec0086d 100644 --- a/docs/tips-guides/oauth.md +++ b/docs/tips-guides/oauth.md @@ -1,4 +1,4 @@ -## Social Login Setup (Google & GitHub, English) +## Social Login Setup (Google, GitHub, Microsoft, Okta) ### Get your Google credentials @@ -52,6 +52,27 @@ To use Microsoft as a social provider, you need to get your Microsoft credential MICROSOFT_TENANT_ID=your_tenant_id # Optional ``` +### Get your Okta credentials + +To use Okta as a social provider, create an OIDC app integration in the Okta Admin Console. + +- In Okta Admin, go to **Applications > Applications** and click **Create App Integration**. +- Choose **Sign-in method: OIDC - OpenID Connect** and **Application type: Web Application**. +- In **Sign-in redirect URIs**, set: + - For local development: `http://localhost:3000/api/auth/callback/okta` + - For production: `https://your-domain.com/api/auth/callback/okta` +- After creation, copy: + - Your **Okta domain/issuer** (e.g. `https://dev-XXXX.okta.com/oauth2/default`). Use this as `OKTA_ISSUER`. + - **Client ID** and **Client Secret**. +- Add your credentials to your `.env` file: + + ```text + OKTA_CLIENT_ID=your_okta_client_id + OKTA_CLIENT_SECRET=your_okta_client_secret + # Full issuer URL, e.g. https://dev-XXXX.okta.com/oauth2/default + OKTA_ISSUER=https://your-okta-domain/oauth2/default + ``` + ## Environment Variable Check Make sure your `.env` file contains the following variables: @@ -74,6 +95,12 @@ MICROSOFT_TENANT_ID=your_microsoft_tenant_id MICROSOFT_FORCE_ACCOUNT_SELECTION=1 +# Okta +OKTA_CLIENT_ID=your_okta_client_id +OKTA_CLIENT_SECRET=your_okta_client_secret +# Full issuer URL (e.g. https://dev-XXXX.okta.com/oauth2/default) +OKTA_ISSUER=https://your-okta-domain/oauth2/default + ``` ## Additional Configuration Options @@ -107,4 +134,4 @@ BETTER_AUTH_URL=https://yourdomain.com ## Done -You can now sign in to better-chatbot using your Google, GitHub or Microsoft account. Restart the application to apply the changes. +You can now sign in to better-chatbot using your Google, GitHub, Microsoft, or Okta account. Restart the application to apply the changes. diff --git a/src/components/auth/sign-in.tsx b/src/components/auth/sign-in.tsx index ad811cf13..f35c4869b 100644 --- a/src/components/auth/sign-in.tsx +++ b/src/components/auth/sign-in.tsx @@ -171,6 +171,15 @@ export default function SignIn({ Microsoft )} + {socialAuthenticationProviders.includes("okta") && ( + + )} )} diff --git a/src/components/auth/social-providers.tsx b/src/components/auth/social-providers.tsx index 06dbda12e..2b6cdbc49 100644 --- a/src/components/auth/social-providers.tsx +++ b/src/components/auth/social-providers.tsx @@ -49,6 +49,17 @@ export default function SocialProviders({ Microsoft )} + {socialAuthenticationProviders.includes("okta") && ( + + )} ); } diff --git a/src/lib/auth/config.ts b/src/lib/auth/config.ts index c2990782a..9edfc6274 100644 --- a/src/lib/auth/config.ts +++ b/src/lib/auth/config.ts @@ -2,9 +2,11 @@ import { GitHubConfigSchema, GoogleConfigSchema, MicrosoftConfigSchema, + OktaConfigSchema, GitHubConfig, GoogleConfig, MicrosoftConfig, + OktaConfig, AuthConfig, AuthConfigSchema, } from "app-types/authentication"; @@ -27,6 +29,7 @@ function parseSocialAuthConfigs() { github?: GitHubConfig; google?: GoogleConfig; microsoft?: MicrosoftConfig; + okta?: OktaConfig; } = {}; const disableSignUp = parseEnvBoolean(process.env.DISABLE_SIGN_UP); @@ -94,6 +97,28 @@ function parseSocialAuthConfigs() { } } + // Okta uses OIDC/OAuth 2.0 with issuer base URL like https://dev-xxxx.okta.com/oauth2/default + if ( + process.env.OKTA_CLIENT_ID && + process.env.OKTA_CLIENT_SECRET && + process.env.OKTA_ISSUER + ) { + const oktaResult = OktaConfigSchema.safeParse({ + clientId: process.env.OKTA_CLIENT_ID, + clientSecret: process.env.OKTA_CLIENT_SECRET, + issuer: process.env.OKTA_ISSUER, + disableSignUp, + }); + if (oktaResult.success) { + configs.okta = oktaResult.data; + experimental_taintUniqueValue( + "Do not pass OKTA_CLIENT_SECRET to the client", + configs, + configs.okta.clientSecret, + ); + } + } + return configs; } diff --git a/src/types/authentication.ts b/src/types/authentication.ts index b2ec01244..9227a9b34 100644 --- a/src/types/authentication.ts +++ b/src/types/authentication.ts @@ -5,6 +5,7 @@ export const SocialAuthenticationProviderSchema = z.enum([ "github", "google", "microsoft", + "okta", ]); export type SocialAuthenticationProvider = z.infer< @@ -32,10 +33,18 @@ export const MicrosoftConfigSchema = z.object({ prompt: z.literal("select_account").optional(), }); +export const OktaConfigSchema = z.object({ + clientId: z.string().min(1), + clientSecret: z.string().min(1), + issuer: z.string().url(), + disableSignUp: z.boolean().optional(), +}); + export const SocialAuthenticationConfigSchema = z.object({ github: GitHubConfigSchema.optional(), google: GoogleConfigSchema.optional(), microsoft: MicrosoftConfigSchema.optional(), + okta: OktaConfigSchema.optional(), }); export const AuthConfigSchema = z.object({ @@ -47,6 +56,7 @@ export const AuthConfigSchema = z.object({ export type GitHubConfig = z.infer; export type GoogleConfig = z.infer; export type MicrosoftConfig = z.infer; +export type OktaConfig = z.infer; export type SocialAuthenticationConfig = z.infer< typeof SocialAuthenticationConfigSchema >;