diff --git a/apps/login/locales/de.json b/apps/login/locales/de.json index a731b2b3c67..f07fde4eb9f 100644 --- a/apps/login/locales/de.json +++ b/apps/login/locales/de.json @@ -14,10 +14,19 @@ "register": "Neuen Benutzer registrieren" }, "password": { - "title": "Passwort", - "description": "Geben Sie Ihr Passwort ein.", - "resetPassword": "Passwort zurücksetzen", - "submit": "Weiter" + "verify": { + "title": "Passwort", + "description": "Geben Sie Ihr Passwort ein.", + "resetPassword": "Passwort zurücksetzen", + "submit": "Weiter" + }, + "set": { + "title": "Passwort festlegen", + "description": "Legen Sie das Passwort für Ihr Konto fest", + "codeSent": "Ein Code wurde an Ihre E-Mail-Adresse gesendet.", + "resend": "Erneut senden", + "submit": "Weiter" + } }, "idp": { "title": "Mit SSO anmelden", diff --git a/apps/login/locales/en.json b/apps/login/locales/en.json index 4eae3c1a4c5..6aca7e220e6 100644 --- a/apps/login/locales/en.json +++ b/apps/login/locales/en.json @@ -14,10 +14,19 @@ "register": "Register new user" }, "password": { - "title": "Password", - "description": "Enter your password.", - "resetPassword": "Reset Password", - "submit": "Continue" + "verify": { + "title": "Password", + "description": "Enter your password.", + "resetPassword": "Reset Password", + "submit": "Continue" + }, + "set": { + "title": "Set Password", + "description": "Set the password for your account", + "codeSent": "A code has been sent to your email address.", + "resend": "Resend code", + "submit": "Continue" + } }, "idp": { "title": "Sign in with SSO", diff --git a/apps/login/locales/es.json b/apps/login/locales/es.json index 4fa10378f28..e730412458b 100644 --- a/apps/login/locales/es.json +++ b/apps/login/locales/es.json @@ -14,10 +14,19 @@ "register": "Registrar nuevo usuario" }, "password": { - "title": "Contraseña", - "description": "Introduce tu contraseña.", - "resetPassword": "Restablecer Contraseña", - "submit": "Continuar" + "verify": { + "title": "Contraseña", + "description": "Introduce tu contraseña.", + "resetPassword": "Restablecer contraseña", + "submit": "Continuar" + }, + "set": { + "title": "Establecer Contraseña", + "description": "Establece la contraseña para tu cuenta", + "codeSent": "Se ha enviado un código a su correo electrónico.", + "resend": "Reenviar código", + "submit": "Continuar" + } }, "idp": { "title": "Iniciar sesión con SSO", diff --git a/apps/login/locales/it.json b/apps/login/locales/it.json index 8f7d4c33440..1104a08d689 100644 --- a/apps/login/locales/it.json +++ b/apps/login/locales/it.json @@ -14,10 +14,19 @@ "register": "Registrati come nuovo utente" }, "password": { - "title": "Password", - "description": "Inserisci la tua password.", - "resetPassword": "Reimposta Password", - "submit": "Continua" + "verify": { + "title": "Password", + "description": "Inserisci la tua password.", + "resetPassword": "Reimposta Password", + "submit": "Continua" + }, + "set": { + "title": "Imposta Password", + "description": "Imposta la password per il tuo account", + "codeSent": "Un codice è stato inviato al tuo indirizzo email.", + "resend": "Invia di nuovo", + "submit": "Continua" + } }, "idp": { "title": "Accedi con SSO", diff --git a/apps/login/src/app/(login)/password/page.tsx b/apps/login/src/app/(login)/password/page.tsx index d6c87850ebb..43cb969dc35 100644 --- a/apps/login/src/app/(login)/password/page.tsx +++ b/apps/login/src/app/(login)/password/page.tsx @@ -32,13 +32,13 @@ export default async function Page({ const branding = await getBrandingSettings(organization); const loginSettings = await getLoginSettings(organization); - console.log(sessionFactors); - return (
-

{sessionFactors?.factors?.user?.displayName ?? t("title")}

-

{t("description")}

+

+ {sessionFactors?.factors?.user?.displayName ?? t("verify.title")} +

+

{t("verify.description")}

{/* show error only if usernames should be shown to be unknown */} {(!sessionFactors || !loginName) && diff --git a/apps/login/src/app/(login)/password/set/page.tsx b/apps/login/src/app/(login)/password/set/page.tsx index 6aa7ba23e80..e99f79ef923 100644 --- a/apps/login/src/app/(login)/password/set/page.tsx +++ b/apps/login/src/app/(login)/password/set/page.tsx @@ -1,4 +1,4 @@ -import { Alert } from "@/components/alert"; +import { Alert, AlertType } from "@/components/alert"; import { DynamicTheme } from "@/components/dynamic-theme"; import { SetPasswordForm } from "@/components/set-password-form"; import { UserAvatar } from "@/components/user-avatar"; @@ -37,8 +37,8 @@ export default async function Page({ return (
-

{sessionFactors?.factors?.user?.displayName ?? t("title")}

-

{t("description")}

+

{sessionFactors?.factors?.user?.displayName ?? t("set.title")}

+

{t("set.description")}

{/* show error only if usernames should be shown to be unknown */} {(!sessionFactors || !loginName) && @@ -57,9 +57,14 @@ export default async function Page({ > )} - {passwordComplexity && loginName ? ( + {t("set.codeSent")} + + {passwordComplexity && + loginName && + sessionFactors?.factors?.user?.id ? ( - {t("resetPassword")} + {t("verify.resetPassword")} )} @@ -284,7 +296,7 @@ export function PasswordForm({ onClick={handleSubmit(submitPasswordAndContinue)} > {loading && } - {t("submit")} + {t("verify.submit")}
diff --git a/apps/login/src/components/set-password-form.tsx b/apps/login/src/components/set-password-form.tsx index 4baff6f6c01..51e3f1325e7 100644 --- a/apps/login/src/components/set-password-form.tsx +++ b/apps/login/src/components/set-password-form.tsx @@ -7,8 +7,8 @@ import { upperCaseValidator, } from "@/helpers/validators"; import { changePassword } from "@/lib/server/password"; -import { RegisterUserResponse } from "@/lib/server/register"; import { PasswordComplexitySettings } from "@zitadel/proto/zitadel/settings/v2/password_settings_pb"; +import { SetPasswordResponse } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; import { useTranslations } from "next-intl"; import { useRouter } from "next/navigation"; import { useState } from "react"; @@ -22,6 +22,7 @@ import { Spinner } from "./spinner"; type Inputs = | { + code: string; password: string; confirmPassword: string; } @@ -31,6 +32,7 @@ type Props = { code?: string; passwordComplexitySettings: PasswordComplexitySettings; loginName: string; + userId: string; organization?: string; authRequestId?: string; }; @@ -39,12 +41,17 @@ export function SetPasswordForm({ passwordComplexitySettings, organization, authRequestId, + loginName, + userId, + code, }: Props) { - const t = useTranslations("register"); + const t = useTranslations("password"); const { register, handleSubmit, watch, formState } = useForm({ mode: "onBlur", - defaultValues: {}, + defaultValues: { + code: code ?? "", + }, }); const [loading, setLoading] = useState(false); @@ -55,9 +62,9 @@ export function SetPasswordForm({ async function submitRegister(values: Inputs) { setLoading(true); const response = await changePassword({ - organization: organization, - authRequestId: authRequestId, + userId: userId, password: values.password, + code: values.code, }).catch(() => { setError("Could not register user"); }); @@ -73,19 +80,18 @@ export function SetPasswordForm({ return; } - const userResponse = response as RegisterUserResponse; + const userResponse = response as SetPasswordResponse & { + sessionId: string; + }; - const params = new URLSearchParams({ userId: userResponse.userId }); + const params = new URLSearchParams({}); - if (userResponse.factors?.user?.loginName) { - params.append("loginName", userResponse.factors.user.loginName); + if (loginName) { + params.append("loginName", loginName); } if (organization) { params.append("organization", organization); } - if (userResponse && userResponse.sessionId) { - params.append("sessionId", userResponse.sessionId); - } // skip verification for now as it is an app based flow // return router.push(`/verify?` + params); @@ -129,6 +135,24 @@ export function SetPasswordForm({ return (
+
+
+ +
+
+ +
+
@@ -179,7 +203,7 @@ export function SetPasswordForm({ onClick={handleSubmit(submitRegister)} > {loading && } - {t("password.submit")} + {t("set.submit")}
diff --git a/apps/login/src/lib/server/password.ts b/apps/login/src/lib/server/password.ts index 6906f43039f..faa0bbeb04c 100644 --- a/apps/login/src/lib/server/password.ts +++ b/apps/login/src/lib/server/password.ts @@ -111,7 +111,7 @@ export async function sendPassword(command: UpdateSessionCommand) { } export async function changePassword(command: { - code?: string; + code: string; userId: string; password: string; }) { @@ -123,5 +123,5 @@ export async function changePassword(command: { } const userId = user.userId; - return setPassword(userId, command.password); + return setPassword(userId, command.password, command.code); } diff --git a/apps/login/src/lib/zitadel.ts b/apps/login/src/lib/zitadel.ts index 014602478c8..846552ddda2 100644 --- a/apps/login/src/lib/zitadel.ts +++ b/apps/login/src/lib/zitadel.ts @@ -28,6 +28,7 @@ import { } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb"; import { PasswordComplexitySettingsSchema } from "@zitadel/proto/zitadel/settings/v2/password_settings_pb"; import type { RedirectURLsJson } from "@zitadel/proto/zitadel/user/v2/idp_pb"; +import { NotificationType } from "@zitadel/proto/zitadel/user/v2/password_pb"; import { SearchQuery, SearchQuerySchema, @@ -495,18 +496,32 @@ export async function passwordReset(userId: string) { return userService.passwordReset( { userId, + medium: { + case: "sendLink", + value: { + notificationType: NotificationType.Email, + }, + }, }, {}, ); } -export async function setPassword(userId: string, password: string) { +export async function setPassword( + userId: string, + password: string, + code: string, +) { return userService.setPassword( { userId, newPassword: { password, }, + verification: { + case: "verificationCode", + value: code, + }, }, {}, );