mirror of
https://github.com/documenso/documenso.git
synced 2025-11-15 09:12:02 +10:00
feat: add oidc support
This commit is contained in:
@ -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';
|
||||
@ -68,9 +69,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();
|
||||
|
||||
@ -256,6 +263,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 (
|
||||
<Form {...form}>
|
||||
<form
|
||||
@ -316,7 +336,7 @@ export const SignInForm = ({ className, initialEmail, isGoogleSSOEnabled }: Sign
|
||||
{isSubmitting ? 'Signing in...' : 'Sign In'}
|
||||
</Button>
|
||||
|
||||
{(isGoogleSSOEnabled || isPasskeyEnabled) && (
|
||||
{(isGoogleSSOEnabled || isPasskeyEnabled || isOIDCSSOEnabled) && (
|
||||
<div className="relative flex items-center justify-center gap-x-4 py-2 text-xs uppercase">
|
||||
<div className="bg-border h-px flex-1" />
|
||||
<span className="text-muted-foreground bg-transparent">Or continue with</span>
|
||||
@ -338,6 +358,20 @@ export const SignInForm = ({ className, initialEmail, isGoogleSSOEnabled }: Sign
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{isOIDCSSOEnabled && (
|
||||
<Button
|
||||
type="button"
|
||||
size="lg"
|
||||
variant="outline"
|
||||
className="bg-background text-muted-foreground border"
|
||||
disabled={isSubmitting}
|
||||
onClick={onSignInWithOIDCClick}
|
||||
>
|
||||
<FaIdCardClip className="mr-2 h-5 w-5" />
|
||||
OIDC
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{isPasskeyEnabled && (
|
||||
<Button
|
||||
type="button"
|
||||
|
||||
@ -52,9 +52,15 @@ export type SignUpFormProps = {
|
||||
className?: string;
|
||||
initialEmail?: string;
|
||||
isGoogleSSOEnabled?: boolean;
|
||||
isOIDCSSOEnabled?: boolean;
|
||||
};
|
||||
|
||||
export const SignUpForm = ({ className, initialEmail, isGoogleSSOEnabled }: SignUpFormProps) => {
|
||||
export const SignUpForm = ({
|
||||
className,
|
||||
initialEmail,
|
||||
isGoogleSSOEnabled,
|
||||
isOIDCSSOEnabled,
|
||||
}: SignUpFormProps) => {
|
||||
const { toast } = useToast();
|
||||
const analytics = useAnalytics();
|
||||
const router = useRouter();
|
||||
@ -121,6 +127,19 @@ export const SignUpForm = ({ className, initialEmail, isGoogleSSOEnabled }: Sign
|
||||
}
|
||||
};
|
||||
|
||||
const onSignUpWithOIDCClick = async () => {
|
||||
try {
|
||||
await signIn('google', { callbackUrl: SIGN_UP_REDIRECT_PATH });
|
||||
} catch (err) {
|
||||
toast({
|
||||
title: 'An unknown error occurred',
|
||||
description:
|
||||
'We encountered an unknown error while attempting to sign you Up. Please try again later.',
|
||||
variant: 'destructive',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Form {...form}>
|
||||
<form
|
||||
@ -221,6 +240,28 @@ export const SignUpForm = ({ className, initialEmail, isGoogleSSOEnabled }: Sign
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
|
||||
{isOIDCSSOEnabled && (
|
||||
<>
|
||||
<div className="relative flex items-center justify-center gap-x-4 py-2 text-xs uppercase">
|
||||
<div className="bg-border h-px flex-1" />
|
||||
<span className="text-muted-foreground bg-transparent">Or</span>
|
||||
<div className="bg-border h-px flex-1" />
|
||||
</div>
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
size="lg"
|
||||
variant={'outline'}
|
||||
className="bg-background text-muted-foreground border"
|
||||
disabled={isSubmitting}
|
||||
onClick={onSignUpWithOIDCClick}
|
||||
>
|
||||
<FcGoogle className="mr-2 h-5 w-5" />
|
||||
Sign Up with OIDC
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</form>
|
||||
</Form>
|
||||
);
|
||||
|
||||
@ -10,6 +10,7 @@ import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
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 { z } from 'zod';
|
||||
|
||||
@ -73,12 +74,14 @@ export type SignUpFormV2Props = {
|
||||
className?: string;
|
||||
initialEmail?: string;
|
||||
isGoogleSSOEnabled?: boolean;
|
||||
isOIDCSSOEnabled?: boolean;
|
||||
};
|
||||
|
||||
export const SignUpFormV2 = ({
|
||||
className,
|
||||
initialEmail,
|
||||
isGoogleSSOEnabled,
|
||||
isOIDCSSOEnabled,
|
||||
}: SignUpFormV2Props) => {
|
||||
const { toast } = useToast();
|
||||
const analytics = useAnalytics();
|
||||
@ -179,6 +182,19 @@ export const SignUpFormV2 = ({
|
||||
}
|
||||
};
|
||||
|
||||
const onSignUpWithOIDCClick = async () => {
|
||||
try {
|
||||
await signIn('oidc', { callbackUrl: SIGN_UP_REDIRECT_PATH });
|
||||
} catch (err) {
|
||||
toast({
|
||||
title: 'An unknown error occurred',
|
||||
description:
|
||||
'We encountered an unknown error while attempting to sign you Up. Please try again later.',
|
||||
variant: 'destructive',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={cn('flex justify-center gap-x-12', className)}>
|
||||
<div className="border-border relative hidden flex-1 overflow-hidden rounded-xl border xl:flex">
|
||||
@ -255,7 +271,7 @@ export const SignUpFormV2 = ({
|
||||
<fieldset
|
||||
className={cn(
|
||||
'flex h-[550px] w-full flex-col gap-y-4',
|
||||
isGoogleSSOEnabled && 'h-[650px]',
|
||||
(isGoogleSSOEnabled || isOIDCSSOEnabled) && 'h-[650px]',
|
||||
)}
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
@ -323,14 +339,18 @@ export const SignUpFormV2 = ({
|
||||
)}
|
||||
/>
|
||||
|
||||
{isGoogleSSOEnabled && (
|
||||
{(isGoogleSSOEnabled || isOIDCSSOEnabled) && (
|
||||
<>
|
||||
<div className="relative flex items-center justify-center gap-x-4 py-2 text-xs uppercase">
|
||||
<div className="bg-border h-px flex-1" />
|
||||
<span className="text-muted-foreground bg-transparent">Or</span>
|
||||
<div className="bg-border h-px flex-1" />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{isGoogleSSOEnabled && (
|
||||
<>
|
||||
<Button
|
||||
type="button"
|
||||
size="lg"
|
||||
@ -345,6 +365,22 @@ export const SignUpFormV2 = ({
|
||||
</>
|
||||
)}
|
||||
|
||||
{isOIDCSSOEnabled && (
|
||||
<>
|
||||
<Button
|
||||
type="button"
|
||||
size="lg"
|
||||
variant={'outline'}
|
||||
className="bg-background text-muted-foreground border"
|
||||
disabled={isSubmitting}
|
||||
onClick={onSignUpWithOIDCClick}
|
||||
>
|
||||
<FaIdCardClip className="mr-2 h-5 w-5" />
|
||||
Sign Up with OIDC
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
|
||||
<p className="text-muted-foreground mt-4 text-sm">
|
||||
Already have an account?{' '}
|
||||
<Link href="/signin" className="text-documenso-700 duration-200 hover:opacity-70">
|
||||
|
||||
Reference in New Issue
Block a user