diff --git a/CHANGELOG.md b/CHANGELOG.md index ccaca8b0..94e94262 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed +- Fixed issue where new oauth providers weren't being display in the login page + ## [4.0.1] - 2025-05-28 ### Fixed diff --git a/packages/web/public/keycloak.svg b/packages/web/public/keycloak.svg new file mode 100644 index 00000000..44798d21 --- /dev/null +++ b/packages/web/public/keycloak.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/web/public/microsoft_entra.svg b/packages/web/public/microsoft_entra.svg new file mode 100644 index 00000000..0ed35fb7 --- /dev/null +++ b/packages/web/public/microsoft_entra.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/packages/web/public/okta.svg b/packages/web/public/okta.svg new file mode 100644 index 00000000..75b1a850 --- /dev/null +++ b/packages/web/public/okta.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/packages/web/src/app/login/components/loginForm.tsx b/packages/web/src/app/login/components/loginForm.tsx index b03a3b3d..132e41ec 100644 --- a/packages/web/src/app/login/components/loginForm.tsx +++ b/packages/web/src/app/login/components/loginForm.tsx @@ -1,12 +1,11 @@ 'use client'; import { Button } from "@/components/ui/button"; -import googleLogo from "@/public/google.svg"; import Image from "next/image"; import { signIn } from "next-auth/react"; import { Fragment, useCallback, useMemo } from "react"; import { Card } from "@/components/ui/card"; -import { cn, getCodeHostIcon } from "@/lib/utils"; +import { cn, getAuthProviderInfo } from "@/lib/utils"; import { MagicLinkForm } from "./magicLinkForm"; import { CredentialsForm } from "./credentialsForm"; import { SourcebotLogo } from "@/app/components/sourcebotLogo"; @@ -22,15 +21,10 @@ const PRIVACY_POLICY_URL = "https://sourcebot.dev/privacy"; interface LoginFormProps { callbackUrl?: string; error?: string; - enabledMethods: { - github: boolean; - google: boolean; - magicLink: boolean; - credentials: boolean; - } + providers: Array<{ id: string; name: string }>; } -export const LoginForm = ({ callbackUrl, error, enabledMethods }: LoginFormProps) => { +export const LoginForm = ({ callbackUrl, error, providers }: LoginFormProps) => { const captureEvent = useCaptureEvent(); const onSignInWithOauth = useCallback((provider: string) => { signIn(provider, { redirectTo: callbackUrl ?? "/" }); @@ -50,6 +44,33 @@ export const LoginForm = ({ callbackUrl, error, enabledMethods }: LoginFormProps } }, [error]); + // Separate OAuth providers from special auth methods + const oauthProviders = providers.filter(p => + !["credentials", "nodemailer"].includes(p.id) + ); + const hasCredentials = providers.some(p => p.id === "credentials"); + const hasMagicLink = providers.some(p => p.id === "nodemailer"); + + // Helper function to get the correct analytics event name + const getLoginEventName = (providerId: string) => { + switch (providerId) { + case "github": + return "wa_login_with_github" as const; + case "google": + return "wa_login_with_google" as const; + case "gitlab": + return "wa_login_with_gitlab" as const; + case "okta": + return "wa_login_with_okta" as const; + case "keycloak": + return "wa_login_with_keycloak" as const; + case "microsoft-entra-id": + return "wa_login_with_microsoft_entra_id" as const; + default: + return "wa_login_with_github" as const; // fallback + } + }; + return (
@@ -71,36 +92,28 @@ export const LoginForm = ({ callbackUrl, error, enabledMethods }: LoginFormProps )} - {enabledMethods.github && ( - { - captureEvent("wa_login_with_github", {}); - onSignInWithOauth("github") - }} - /> - )} - {enabledMethods.google && ( - { - captureEvent("wa_login_with_google", {}); - onSignInWithOauth("google") - }} - /> - )} - + ...(oauthProviders.length > 0 ? [ +
+ {oauthProviders.map((provider) => { + const providerInfo = getAuthProviderInfo(provider.id); + return ( + { + captureEvent(getLoginEventName(provider.id), {}); + onSignInWithOauth(provider.id); + }} + /> + ); + })} +
] : []), - ...(enabledMethods.magicLink ? [ + ...(hasMagicLink ? [ ] : []), - ...(enabledMethods.credentials ? [ + ...(hasCredentials ? [ ] : []) ]} @@ -120,7 +133,7 @@ const ProviderButton = ({ className, }: { name: string; - logo: { src: string, className?: string }; + logo: { src: string, className?: string } | null; onClick: () => void; className?: string; }) => { diff --git a/packages/web/src/app/login/page.tsx b/packages/web/src/app/login/page.tsx index 081c2bbb..1487d182 100644 --- a/packages/web/src/app/login/page.tsx +++ b/packages/web/src/app/login/page.tsx @@ -20,11 +20,11 @@ export default async function Login({ searchParams }: LoginProps) { } const providers = getProviders(); - const providerMap = providers + const providerData = providers .map((provider) => { if (typeof provider === "function") { - const providerData = provider() - return { id: providerData.id, name: providerData.name } + const providerInfo = provider() + return { id: providerInfo.id, name: providerInfo.name } } else { return { id: provider.id, name: provider.name } } @@ -36,12 +36,7 @@ export default async function Login({ searchParams }: LoginProps) { provider.id === "github"), - google: providerMap.some(provider => provider.id === "google"), - magicLink: providerMap.some(provider => provider.id === "nodemailer"), - credentials: providerMap.some(provider => provider.id === "credentials"), - }} + providers={providerData} />