diff --git a/.env.example b/.env.example index 6a81f72e2..4919f0053 100644 --- a/.env.example +++ b/.env.example @@ -13,6 +13,10 @@ NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY="DEADBEEF" NEXT_PRIVATE_GOOGLE_CLIENT_ID="" NEXT_PRIVATE_GOOGLE_CLIENT_SECRET="" +NEXT_PRIVATE_OIDC_WELL_KNOWN="" +NEXT_PRIVATE_OIDC_CLIENT_ID="" +NEXT_PRIVATE_OIDC_CLIENT_SECRET="" + # [[URLS]] NEXT_PUBLIC_WEBAPP_URL="http://localhost:3000" NEXT_PUBLIC_MARKETING_URL="http://localhost:3001" diff --git a/apps/web/process-env.d.ts b/apps/web/process-env.d.ts index 0c00cb4c1..63a341060 100644 --- a/apps/web/process-env.d.ts +++ b/apps/web/process-env.d.ts @@ -12,5 +12,9 @@ declare namespace NodeJS { NEXT_PRIVATE_GOOGLE_CLIENT_ID: string; NEXT_PRIVATE_GOOGLE_CLIENT_SECRET: string; + + NEXT_PRIVATE_OIDC_WELL_KNOWN: string; + NEXT_PRIVATE_OIDC_CLIENT_ID: string; + NEXT_PRIVATE_OIDC_CLIENT_SECRET: string; } } diff --git a/apps/web/src/app/(unauthenticated)/signin/page.tsx b/apps/web/src/app/(unauthenticated)/signin/page.tsx index 21136f2e6..a0599ac1a 100644 --- a/apps/web/src/app/(unauthenticated)/signin/page.tsx +++ b/apps/web/src/app/(unauthenticated)/signin/page.tsx @@ -4,7 +4,7 @@ import { redirect } from 'next/navigation'; import { env } from 'next-runtime-env'; -import { IS_GOOGLE_SSO_ENABLED } from '@documenso/lib/constants/auth'; +import { IS_GOOGLE_SSO_ENABLED, IS_OIDC_SSO_ENABLED } from '@documenso/lib/constants/auth'; import { decryptSecondaryData } from '@documenso/lib/server-only/crypto/decrypt'; import { SignInForm } from '~/components/forms/signin'; @@ -37,10 +37,13 @@ export default function SignInPage({ searchParams }: SignInPageProps) {
Welcome back, we are lucky to have you.
-diff --git a/apps/web/src/app/(unauthenticated)/signup/page.tsx b/apps/web/src/app/(unauthenticated)/signup/page.tsx index c7284fac6..2373af770 100644 --- a/apps/web/src/app/(unauthenticated)/signup/page.tsx +++ b/apps/web/src/app/(unauthenticated)/signup/page.tsx @@ -3,7 +3,7 @@ import { redirect } from 'next/navigation'; import { env } from 'next-runtime-env'; -import { IS_GOOGLE_SSO_ENABLED } from '@documenso/lib/constants/auth'; +import { IS_GOOGLE_SSO_ENABLED, IS_OIDC_SSO_ENABLED } from '@documenso/lib/constants/auth'; import { decryptSecondaryData } from '@documenso/lib/server-only/crypto/decrypt'; import { SignUpFormV2 } from '~/components/forms/v2/signup'; @@ -37,6 +37,7 @@ export default function SignUpPage({ searchParams }: SignUpPageProps) { className="w-screen max-w-screen-2xl px-4 md:px-16 lg:-my-16" initialEmail={email || undefined} isGoogleSSOEnabled={IS_GOOGLE_SSO_ENABLED} + isOIDCSSOEnabled={IS_OIDC_SSO_ENABLED} /> ); } diff --git a/apps/web/src/components/forms/signin.tsx b/apps/web/src/components/forms/signin.tsx index 59b8af6c7..e86ad492f 100644 --- a/apps/web/src/components/forms/signin.tsx +++ b/apps/web/src/components/forms/signin.tsx @@ -10,6 +10,7 @@ import { browserSupportsWebAuthn, startAuthentication } from '@simplewebauthn/br import { KeyRoundIcon } from 'lucide-react'; import { signIn } from 'next-auth/react'; import { useForm } from 'react-hook-form'; +import { FaIdCardClip } from 'react-icons/fa6'; import { FcGoogle } from 'react-icons/fc'; import { match } from 'ts-pattern'; import { z } from 'zod'; @@ -69,9 +70,15 @@ export type SignInFormProps = { className?: string; initialEmail?: string; isGoogleSSOEnabled?: boolean; + isOIDCSSOEnabled?: boolean; }; -export const SignInForm = ({ className, initialEmail, isGoogleSSOEnabled }: SignInFormProps) => { +export const SignInForm = ({ + className, + initialEmail, + isGoogleSSOEnabled, + isOIDCSSOEnabled, +}: SignInFormProps) => { const { toast } = useToast(); const { getFlag } = useFeatureFlags(); @@ -257,6 +264,19 @@ export const SignInForm = ({ className, initialEmail, isGoogleSSOEnabled }: Sign } }; + const onSignInWithOIDCClick = async () => { + try { + await signIn('oidc', { callbackUrl: LOGIN_REDIRECT_PATH }); + } catch (err) { + toast({ + title: 'An unknown error occurred', + description: + 'We encountered an unknown error while attempting to sign you In. Please try again later.', + variant: 'destructive', + }); + } + }; + return (