Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions docs/tips-guides/oauth.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Social Login Setup (Google & GitHub, English)
## Social Login Setup (Google, GitHub, Microsoft, Okta)

### Get your Google credentials

Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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.
9 changes: 9 additions & 0 deletions src/components/auth/sign-in.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,15 @@ export default function SignIn({
Microsoft
</Button>
)}
{socialAuthenticationProviders.includes("okta") && (
<Button
variant="outline"
onClick={() => handleSocialSignIn("okta")}
className="flex-1 w-full"
>
Okta
</Button>
)}
</div>
</>
)}
Expand Down
11 changes: 11 additions & 0 deletions src/components/auth/social-providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ export default function SocialProviders({
Microsoft
</Button>
)}
{socialAuthenticationProviders.includes("okta") && (
<Button
variant="outline"
onClick={() => onSocialProviderClick("okta")}
className="flex-1 w-full"
data-testid="okta-signup-button"
>
{/* No dedicated Okta icon in UI set; using text label */}
Okta
</Button>
)}
</div>
);
}
25 changes: 25 additions & 0 deletions src/lib/auth/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import {
GitHubConfigSchema,
GoogleConfigSchema,
MicrosoftConfigSchema,
OktaConfigSchema,
GitHubConfig,
GoogleConfig,
MicrosoftConfig,
OktaConfig,
AuthConfig,
AuthConfigSchema,
} from "app-types/authentication";
Expand All @@ -27,6 +29,7 @@ function parseSocialAuthConfigs() {
github?: GitHubConfig;
google?: GoogleConfig;
microsoft?: MicrosoftConfig;
okta?: OktaConfig;
} = {};
const disableSignUp = parseEnvBoolean(process.env.DISABLE_SIGN_UP);

Expand Down Expand 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;
}

Expand Down
10 changes: 10 additions & 0 deletions src/types/authentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const SocialAuthenticationProviderSchema = z.enum([
"github",
"google",
"microsoft",
"okta",
]);

export type SocialAuthenticationProvider = z.infer<
Expand Down Expand Up @@ -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({
Expand All @@ -47,6 +56,7 @@ export const AuthConfigSchema = z.object({
export type GitHubConfig = z.infer<typeof GitHubConfigSchema>;
export type GoogleConfig = z.infer<typeof GoogleConfigSchema>;
export type MicrosoftConfig = z.infer<typeof MicrosoftConfigSchema>;
export type OktaConfig = z.infer<typeof OktaConfigSchema>;
export type SocialAuthenticationConfig = z.infer<
typeof SocialAuthenticationConfigSchema
>;
Expand Down