diff --git a/apps/login/locales/de.json b/apps/login/locales/de.json index 05183374b76..55a63551204 100644 --- a/apps/login/locales/de.json +++ b/apps/login/locales/de.json @@ -222,7 +222,6 @@ "termsOfService": "Nutzungsbedingungen", "privacyPolicy": "Datenschutzrichtlinie", "submit": "Weiter", - "orUseIDP": "oder verwenden Sie einen Identitätsanbieter", "password": { "title": "Passwort festlegen", "description": "Legen Sie das Passwort für Ihr Konto fest", diff --git a/apps/login/locales/en.json b/apps/login/locales/en.json index 5c47e8e64fe..8d8c11ec3be 100644 --- a/apps/login/locales/en.json +++ b/apps/login/locales/en.json @@ -222,7 +222,6 @@ "termsOfService": "Terms of Service", "privacyPolicy": "Privacy Policy", "submit": "Continue", - "orUseIDP": "or use an Identity Provider", "password": { "title": "Set Password", "description": "Set the password for your account", diff --git a/apps/login/locales/es.json b/apps/login/locales/es.json index 1d44cb53cee..82f1e9335d5 100644 --- a/apps/login/locales/es.json +++ b/apps/login/locales/es.json @@ -222,7 +222,6 @@ "termsOfService": "Términos de Servicio", "privacyPolicy": "Política de Privacidad", "submit": "Continuar", - "orUseIDP": "o usa un Proveedor de Identidad", "password": { "title": "Establecer Contraseña", "description": "Establece la contraseña para tu cuenta", diff --git a/apps/login/locales/it.json b/apps/login/locales/it.json index 40f59cd9e8e..815efb5a355 100644 --- a/apps/login/locales/it.json +++ b/apps/login/locales/it.json @@ -222,7 +222,6 @@ "termsOfService": "Termini di Servizio", "privacyPolicy": "Informativa sulla Privacy", "submit": "Continua", - "orUseIDP": "o usa un Identity Provider", "password": { "title": "Imposta Password", "description": "Imposta la password per il tuo account", diff --git a/apps/login/locales/pl.json b/apps/login/locales/pl.json index 5cb69ad2074..ae81ba7f39f 100644 --- a/apps/login/locales/pl.json +++ b/apps/login/locales/pl.json @@ -222,7 +222,6 @@ "termsOfService": "Regulamin", "privacyPolicy": "Polityka prywatności", "submit": "Kontynuuj", - "orUseIDP": "lub użyj dostawcy tożsamości", "password": { "title": "Ustaw hasło", "description": "Ustaw hasło dla swojego konta", diff --git a/apps/login/locales/ru.json b/apps/login/locales/ru.json index caf1366cf10..f5e91066dbd 100644 --- a/apps/login/locales/ru.json +++ b/apps/login/locales/ru.json @@ -222,7 +222,6 @@ "termsOfService": "Условия использования", "privacyPolicy": "Политика конфиденциальности", "submit": "Продолжить", - "orUseIDP": "или используйте Identity Provider", "password": { "title": "Установить пароль", "description": "Установите пароль для вашего аккаунта", diff --git a/apps/login/locales/zh.json b/apps/login/locales/zh.json index 5d87b5d8d70..3ec2ec31e90 100644 --- a/apps/login/locales/zh.json +++ b/apps/login/locales/zh.json @@ -222,7 +222,6 @@ "termsOfService": "服务条款", "privacyPolicy": "隐私政策", "submit": "继续", - "orUseIDP": "或使用身份提供者", "password": { "title": "设置密码", "description": "为您的账户设置密码", diff --git a/apps/login/src/app/(login)/register/page.tsx b/apps/login/src/app/(login)/register/page.tsx index 5a11ca1f895..2168813c40d 100644 --- a/apps/login/src/app/(login)/register/page.tsx +++ b/apps/login/src/app/(login)/register/page.tsx @@ -20,12 +20,10 @@ import { headers } from "next/headers"; export async function generateMetadata(): Promise { const t = await getTranslations("register"); - return { title: t('title')}; + return { title: t("title") }; } -export default async function Page(props: { - searchParams: Promise>; -}) { +export default async function Page(props: { searchParams: Promise> }) { const searchParams = await props.searchParams; let { firstname, lastname, email, organization, requestId } = searchParams; @@ -104,12 +102,9 @@ export default async function Page(props: { {legal && passwordComplexitySettings && organization && - (loginSettings.allowUsernamePassword || - loginSettings.passkeysType == PasskeysType.ALLOWED) && ( + (loginSettings.allowUsernamePassword || loginSettings.passkeysType == PasskeysType.ALLOWED) && ( -
-

- -

-
- { + const hasTosLink = !!legal?.tosLink; + const hasPrivacyLink = !!legal?.privacyPolicyLink; + + // Check that all required checkboxes are accepted + return ( + (!hasTosLink || newState.tosAccepted) && + (!hasPrivacyLink || newState.privacyPolicyAccepted) + ); + }; + return ( <>

@@ -50,16 +62,17 @@ export function PrivacyPolicyCheckboxes({ legal, onChange }: Props) {

{ - setAcceptanceState({ + const newState = { ...acceptanceState, tosAccepted: checked, - }); - onChange(checked && acceptanceState.privacyPolicyAccepted); + }; + setAcceptanceState(newState); + onChange(checkAllAccepted(newState)); }} - data-testid="privacy-policy-checkbox" + data-testid="tos-checkbox" />
@@ -75,25 +88,22 @@ export function PrivacyPolicyCheckboxes({ legal, onChange }: Props) {
{ - setAcceptanceState({ + const newState = { ...acceptanceState, privacyPolicyAccepted: checked, - }); - onChange(checked && acceptanceState.tosAccepted); + }; + setAcceptanceState(newState); + onChange(checkAllAccepted(newState)); }} - data-testid="tos-checkbox" + data-testid="privacy-policy-checkbox" />

- +

diff --git a/apps/login/src/components/register-form.tsx b/apps/login/src/components/register-form.tsx index bf44ad2864e..a8f8b0962b3 100644 --- a/apps/login/src/components/register-form.tsx +++ b/apps/login/src/components/register-form.tsx @@ -2,20 +2,13 @@ import { registerUser } from "@/lib/server/register"; import { LegalAndSupportSettings } from "@zitadel/proto/zitadel/settings/v2/legal_settings_pb"; -import { - LoginSettings, - PasskeysType, -} from "@zitadel/proto/zitadel/settings/v2/login_settings_pb"; +import { LoginSettings, PasskeysType } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb"; import { useRouter } from "next/navigation"; import { useState } from "react"; import { useTranslations } from "next-intl"; import { FieldValues, useForm } from "react-hook-form"; import { Alert, AlertType } from "./alert"; -import { - AuthenticationMethod, - AuthenticationMethodRadio, - methods, -} from "./authentication-method-radio"; +import { AuthenticationMethod, AuthenticationMethodRadio, methods } from "./authentication-method-radio"; import { BackButton } from "./back-button"; import { Button, ButtonVariants } from "./button"; import { TextInput } from "./input"; @@ -98,10 +91,7 @@ export function RegisterForm({ return response; } - async function submitAndContinue( - value: Inputs, - withPassword: boolean = false, - ) { + async function submitAndContinue(value: Inputs, withPassword: boolean = false) { const registerParams: any = value; if (organization) { @@ -114,9 +104,7 @@ export function RegisterForm({ // redirect user to /register/password if password is chosen if (withPassword) { - return router.push( - `/register/password?` + new URLSearchParams(registerParams), - ); + return router.push(`/register/password?` + new URLSearchParams(registerParams)); } else { return submitAndRegister(value); } @@ -125,6 +113,11 @@ export function RegisterForm({ const { errors } = formState; const [tosAndPolicyAccepted, setTosAndPolicyAccepted] = useState(false); + + // Check if legal acceptance is required + const isLegalAcceptanceRequired = !!(legal?.tosLink || legal?.privacyPolicyLink); + const canSubmit = formState.isValid && (!isLegalAcceptanceRequired || tosAndPolicyAccepted); + return (
@@ -162,38 +155,27 @@ export function RegisterForm({ />
- {legal && ( - + {(legal?.tosLink || legal?.privacyPolicyLink) && ( + )} {/* show chooser if both methods are allowed */} - {loginSettings && - loginSettings.allowUsernamePassword && - loginSettings.passkeysType == PasskeysType.ALLOWED && ( - <> -

- -

+ {loginSettings && loginSettings.allowUsernamePassword && loginSettings.passkeysType == PasskeysType.ALLOWED && ( + <> +

+ +

-
- -
- - )} +
+ +
+ + )} {!loginSettings?.allowUsernamePassword && loginSettings?.passkeysType !== PasskeysType.ALLOWED && (!loginSettings?.allowExternalIdp || !idpCount) && (
- +
)} @@ -209,11 +191,10 @@ export function RegisterForm({