diff --git a/packages/experience/src/hooks/use-single-sign-on-watch.ts b/packages/experience/src/hooks/use-single-sign-on-watch.ts index 12c1c92f7..767fbf4b1 100644 --- a/packages/experience/src/hooks/use-single-sign-on-watch.ts +++ b/packages/experience/src/hooks/use-single-sign-on-watch.ts @@ -1,4 +1,9 @@ -import { SignInIdentifier, experience, type SsoConnectorMetadata } from '@logto/schemas'; +import { + AgreeToTermsPolicy, + SignInIdentifier, + experience, + type SsoConnectorMetadata, +} from '@logto/schemas'; import { useEffect, useCallback, useContext } from 'react'; import { useNavigate } from 'react-router-dom'; @@ -11,6 +16,7 @@ import useSingleSignOn from '@/hooks/use-single-sign-on'; import { validateEmail } from '@/utils/form'; import { useSieMethods } from './use-sie'; +import useTerms from './use-terms'; const useSingleSignOnWatch = (identifierInput?: IdentifierInputValue) => { const navigate = useNavigate(); @@ -26,6 +32,8 @@ const useSingleSignOnWatch = (identifierInput?: IdentifierInputValue) => { const singleSignOn = useSingleSignOn(); + const { termsValidation, agreeToTermsPolicy } = useTerms(); + // Silently check if the email is registered with any SSO connectors const fetchSsoConnectors = useCallback( async (email: string) => { @@ -65,6 +73,13 @@ const useSingleSignOnWatch = (identifierInput?: IdentifierInputValue) => { return; } + /** + * Check if the user has agreed to the terms and privacy policy before single sign on when the policy is set to `Manual` + */ + if (agreeToTermsPolicy === AgreeToTermsPolicy.Manual && !(await termsValidation())) { + return; + } + // If there is only one connector, we can directly invoke the SSO flow if (ssoConnectors.length === 1 && ssoConnectors[0]?.id) { await singleSignOn(ssoConnectors[0].id); @@ -72,7 +87,14 @@ const useSingleSignOnWatch = (identifierInput?: IdentifierInputValue) => { } navigate(`/${experience.routes.sso}/connectors`); - }, [navigate, showSingleSignOnForm, singleSignOn, ssoConnectors]); + }, [ + agreeToTermsPolicy, + navigate, + showSingleSignOnForm, + singleSignOn, + ssoConnectors, + termsValidation, + ]); useEffect(() => { if (!singleSignOnEnabled) { diff --git a/packages/experience/src/pages/Register/IdentifierRegisterForm/index.tsx b/packages/experience/src/pages/Register/IdentifierRegisterForm/index.tsx index af0dc5734..26ad7768b 100644 --- a/packages/experience/src/pages/Register/IdentifierRegisterForm/index.tsx +++ b/packages/experience/src/pages/Register/IdentifierRegisterForm/index.tsx @@ -137,8 +137,7 @@ const IdentifierRegisterForm = ({ className, autoFocus, signUpMethods }: Props) * Hide the terms checkbox when the policy is set to `Automatic`. * In registration, the terms checkbox is always shown for `Manual` and `ManualRegistrationOnly` policies. */ - (showSingleSignOnForm || agreeToTermsPolicy === AgreeToTermsPolicy.Automatic) && - styles.hidden + agreeToTermsPolicy === AgreeToTermsPolicy.Automatic && styles.hidden )} /> diff --git a/packages/experience/src/pages/SignIn/IdentifierSignInForm/index.tsx b/packages/experience/src/pages/SignIn/IdentifierSignInForm/index.tsx index d5d924ea4..af0869471 100644 --- a/packages/experience/src/pages/SignIn/IdentifierSignInForm/index.tsx +++ b/packages/experience/src/pages/SignIn/IdentifierSignInForm/index.tsx @@ -137,8 +137,7 @@ const IdentifierSignInForm = ({ className, autoFocus, signInMethods }: Props) => className={classNames( styles.terms, // For sign in, only show the terms checkbox if the terms policy is manual - (showSingleSignOnForm || agreeToTermsPolicy !== AgreeToTermsPolicy.Manual) && - styles.hidden + agreeToTermsPolicy !== AgreeToTermsPolicy.Manual && styles.hidden )} /> diff --git a/packages/experience/src/pages/SignIn/PasswordSignInForm/index.tsx b/packages/experience/src/pages/SignIn/PasswordSignInForm/index.tsx index 5658d2b13..931716a81 100644 --- a/packages/experience/src/pages/SignIn/PasswordSignInForm/index.tsx +++ b/packages/experience/src/pages/SignIn/PasswordSignInForm/index.tsx @@ -160,8 +160,7 @@ const PasswordSignInForm = ({ className, autoFocus, signInMethods }: Props) => { className={classNames( styles.terms, // For sign in, only show the terms checkbox if the terms policy is manual - (showSingleSignOnForm || agreeToTermsPolicy !== AgreeToTermsPolicy.Manual) && - styles.hidden + agreeToTermsPolicy !== AgreeToTermsPolicy.Manual && styles.hidden )} />