mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-12 07:24:51 +00:00
redirect to /set
This commit is contained in:
@@ -14,10 +14,19 @@
|
|||||||
"register": "Neuen Benutzer registrieren"
|
"register": "Neuen Benutzer registrieren"
|
||||||
},
|
},
|
||||||
"password": {
|
"password": {
|
||||||
"title": "Passwort",
|
"verify": {
|
||||||
"description": "Geben Sie Ihr Passwort ein.",
|
"title": "Passwort",
|
||||||
"resetPassword": "Passwort zurücksetzen",
|
"description": "Geben Sie Ihr Passwort ein.",
|
||||||
"submit": "Weiter"
|
"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": {
|
"idp": {
|
||||||
"title": "Mit SSO anmelden",
|
"title": "Mit SSO anmelden",
|
||||||
|
|||||||
@@ -14,10 +14,19 @@
|
|||||||
"register": "Register new user"
|
"register": "Register new user"
|
||||||
},
|
},
|
||||||
"password": {
|
"password": {
|
||||||
"title": "Password",
|
"verify": {
|
||||||
"description": "Enter your password.",
|
"title": "Password",
|
||||||
"resetPassword": "Reset Password",
|
"description": "Enter your password.",
|
||||||
"submit": "Continue"
|
"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": {
|
"idp": {
|
||||||
"title": "Sign in with SSO",
|
"title": "Sign in with SSO",
|
||||||
|
|||||||
@@ -14,10 +14,19 @@
|
|||||||
"register": "Registrar nuevo usuario"
|
"register": "Registrar nuevo usuario"
|
||||||
},
|
},
|
||||||
"password": {
|
"password": {
|
||||||
"title": "Contraseña",
|
"verify": {
|
||||||
"description": "Introduce tu contraseña.",
|
"title": "Contraseña",
|
||||||
"resetPassword": "Restablecer Contraseña",
|
"description": "Introduce tu contraseña.",
|
||||||
"submit": "Continuar"
|
"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": {
|
"idp": {
|
||||||
"title": "Iniciar sesión con SSO",
|
"title": "Iniciar sesión con SSO",
|
||||||
|
|||||||
@@ -14,10 +14,19 @@
|
|||||||
"register": "Registrati come nuovo utente"
|
"register": "Registrati come nuovo utente"
|
||||||
},
|
},
|
||||||
"password": {
|
"password": {
|
||||||
"title": "Password",
|
"verify": {
|
||||||
"description": "Inserisci la tua password.",
|
"title": "Password",
|
||||||
"resetPassword": "Reimposta Password",
|
"description": "Inserisci la tua password.",
|
||||||
"submit": "Continua"
|
"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": {
|
"idp": {
|
||||||
"title": "Accedi con SSO",
|
"title": "Accedi con SSO",
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ export default async function Page({
|
|||||||
const branding = await getBrandingSettings(organization);
|
const branding = await getBrandingSettings(organization);
|
||||||
const loginSettings = await getLoginSettings(organization);
|
const loginSettings = await getLoginSettings(organization);
|
||||||
|
|
||||||
console.log(sessionFactors);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DynamicTheme branding={branding}>
|
<DynamicTheme branding={branding}>
|
||||||
<div className="flex flex-col items-center space-y-4">
|
<div className="flex flex-col items-center space-y-4">
|
||||||
<h1>{sessionFactors?.factors?.user?.displayName ?? t("title")}</h1>
|
<h1>
|
||||||
<p className="ztdl-p mb-6 block">{t("description")}</p>
|
{sessionFactors?.factors?.user?.displayName ?? t("verify.title")}
|
||||||
|
</h1>
|
||||||
|
<p className="ztdl-p mb-6 block">{t("verify.description")}</p>
|
||||||
|
|
||||||
{/* show error only if usernames should be shown to be unknown */}
|
{/* show error only if usernames should be shown to be unknown */}
|
||||||
{(!sessionFactors || !loginName) &&
|
{(!sessionFactors || !loginName) &&
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Alert } from "@/components/alert";
|
import { Alert, AlertType } from "@/components/alert";
|
||||||
import { DynamicTheme } from "@/components/dynamic-theme";
|
import { DynamicTheme } from "@/components/dynamic-theme";
|
||||||
import { SetPasswordForm } from "@/components/set-password-form";
|
import { SetPasswordForm } from "@/components/set-password-form";
|
||||||
import { UserAvatar } from "@/components/user-avatar";
|
import { UserAvatar } from "@/components/user-avatar";
|
||||||
@@ -37,8 +37,8 @@ export default async function Page({
|
|||||||
return (
|
return (
|
||||||
<DynamicTheme branding={branding}>
|
<DynamicTheme branding={branding}>
|
||||||
<div className="flex flex-col items-center space-y-4">
|
<div className="flex flex-col items-center space-y-4">
|
||||||
<h1>{sessionFactors?.factors?.user?.displayName ?? t("title")}</h1>
|
<h1>{sessionFactors?.factors?.user?.displayName ?? t("set.title")}</h1>
|
||||||
<p className="ztdl-p mb-6 block">{t("description")}</p>
|
<p className="ztdl-p mb-6 block">{t("set.description")}</p>
|
||||||
|
|
||||||
{/* show error only if usernames should be shown to be unknown */}
|
{/* show error only if usernames should be shown to be unknown */}
|
||||||
{(!sessionFactors || !loginName) &&
|
{(!sessionFactors || !loginName) &&
|
||||||
@@ -57,9 +57,14 @@ export default async function Page({
|
|||||||
></UserAvatar>
|
></UserAvatar>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{passwordComplexity && loginName ? (
|
<Alert type={AlertType.INFO}>{t("set.codeSent")}</Alert>
|
||||||
|
|
||||||
|
{passwordComplexity &&
|
||||||
|
loginName &&
|
||||||
|
sessionFactors?.factors?.user?.id ? (
|
||||||
<SetPasswordForm
|
<SetPasswordForm
|
||||||
code={code}
|
code={code}
|
||||||
|
userId={sessionFactors.factors.user.id}
|
||||||
loginName={loginName}
|
loginName={loginName}
|
||||||
authRequestId={authRequestId}
|
authRequestId={authRequestId}
|
||||||
organization={organization}
|
organization={organization}
|
||||||
|
|||||||
@@ -87,13 +87,25 @@ export function PasswordForm({
|
|||||||
|
|
||||||
if (response && "error" in response) {
|
if (response && "error" in response) {
|
||||||
setError(response.error);
|
setError(response.error);
|
||||||
} else {
|
return;
|
||||||
setInfo("Password was reset. Please check your email.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setInfo("Password was reset. Please check your email.");
|
||||||
|
|
||||||
return response;
|
setLoading(false);
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
loginName: loginName,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (organization) {
|
||||||
|
params.append("organization", organization);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authRequestId) {
|
||||||
|
params.append("authRequestId", authRequestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return router.push("/password/set?" + params);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitPasswordAndContinue(
|
async function submitPasswordAndContinue(
|
||||||
@@ -247,7 +259,7 @@ export function PasswordForm({
|
|||||||
type="button"
|
type="button"
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
>
|
>
|
||||||
{t("resetPassword")}
|
{t("verify.resetPassword")}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -284,7 +296,7 @@ export function PasswordForm({
|
|||||||
onClick={handleSubmit(submitPasswordAndContinue)}
|
onClick={handleSubmit(submitPasswordAndContinue)}
|
||||||
>
|
>
|
||||||
{loading && <Spinner className="h-5 w-5 mr-2" />}
|
{loading && <Spinner className="h-5 w-5 mr-2" />}
|
||||||
{t("submit")}
|
{t("verify.submit")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import {
|
|||||||
upperCaseValidator,
|
upperCaseValidator,
|
||||||
} from "@/helpers/validators";
|
} from "@/helpers/validators";
|
||||||
import { changePassword } from "@/lib/server/password";
|
import { changePassword } from "@/lib/server/password";
|
||||||
import { RegisterUserResponse } from "@/lib/server/register";
|
|
||||||
import { PasswordComplexitySettings } from "@zitadel/proto/zitadel/settings/v2/password_settings_pb";
|
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 { useTranslations } from "next-intl";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
@@ -22,6 +22,7 @@ import { Spinner } from "./spinner";
|
|||||||
|
|
||||||
type Inputs =
|
type Inputs =
|
||||||
| {
|
| {
|
||||||
|
code: string;
|
||||||
password: string;
|
password: string;
|
||||||
confirmPassword: string;
|
confirmPassword: string;
|
||||||
}
|
}
|
||||||
@@ -31,6 +32,7 @@ type Props = {
|
|||||||
code?: string;
|
code?: string;
|
||||||
passwordComplexitySettings: PasswordComplexitySettings;
|
passwordComplexitySettings: PasswordComplexitySettings;
|
||||||
loginName: string;
|
loginName: string;
|
||||||
|
userId: string;
|
||||||
organization?: string;
|
organization?: string;
|
||||||
authRequestId?: string;
|
authRequestId?: string;
|
||||||
};
|
};
|
||||||
@@ -39,12 +41,17 @@ export function SetPasswordForm({
|
|||||||
passwordComplexitySettings,
|
passwordComplexitySettings,
|
||||||
organization,
|
organization,
|
||||||
authRequestId,
|
authRequestId,
|
||||||
|
loginName,
|
||||||
|
userId,
|
||||||
|
code,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const t = useTranslations("register");
|
const t = useTranslations("password");
|
||||||
|
|
||||||
const { register, handleSubmit, watch, formState } = useForm<Inputs>({
|
const { register, handleSubmit, watch, formState } = useForm<Inputs>({
|
||||||
mode: "onBlur",
|
mode: "onBlur",
|
||||||
defaultValues: {},
|
defaultValues: {
|
||||||
|
code: code ?? "",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
@@ -55,9 +62,9 @@ export function SetPasswordForm({
|
|||||||
async function submitRegister(values: Inputs) {
|
async function submitRegister(values: Inputs) {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const response = await changePassword({
|
const response = await changePassword({
|
||||||
organization: organization,
|
userId: userId,
|
||||||
authRequestId: authRequestId,
|
|
||||||
password: values.password,
|
password: values.password,
|
||||||
|
code: values.code,
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
setError("Could not register user");
|
setError("Could not register user");
|
||||||
});
|
});
|
||||||
@@ -73,19 +80,18 @@ export function SetPasswordForm({
|
|||||||
return;
|
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) {
|
if (loginName) {
|
||||||
params.append("loginName", userResponse.factors.user.loginName);
|
params.append("loginName", loginName);
|
||||||
}
|
}
|
||||||
if (organization) {
|
if (organization) {
|
||||||
params.append("organization", 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
|
// skip verification for now as it is an app based flow
|
||||||
// return router.push(`/verify?` + params);
|
// return router.push(`/verify?` + params);
|
||||||
@@ -129,6 +135,24 @@ export function SetPasswordForm({
|
|||||||
return (
|
return (
|
||||||
<form className="w-full">
|
<form className="w-full">
|
||||||
<div className="pt-4 grid grid-cols-1 gap-4 mb-4">
|
<div className="pt-4 grid grid-cols-1 gap-4 mb-4">
|
||||||
|
<div className="flex flex-row items-end">
|
||||||
|
<div className="flex-1">
|
||||||
|
<TextInput
|
||||||
|
type="text"
|
||||||
|
required
|
||||||
|
{...register("code", {
|
||||||
|
required: "This field is required",
|
||||||
|
})}
|
||||||
|
label="Code"
|
||||||
|
error={errors.code?.message as string}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="ml-4 mb-1">
|
||||||
|
<Button variant={ButtonVariants.Secondary}>
|
||||||
|
{t("set.resend")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="">
|
<div className="">
|
||||||
<TextInput
|
<TextInput
|
||||||
type="password"
|
type="password"
|
||||||
@@ -137,7 +161,7 @@ export function SetPasswordForm({
|
|||||||
{...register("password", {
|
{...register("password", {
|
||||||
required: "You have to provide a password!",
|
required: "You have to provide a password!",
|
||||||
})}
|
})}
|
||||||
label="Password"
|
label="New Password"
|
||||||
error={errors.password?.message as string}
|
error={errors.password?.message as string}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -179,7 +203,7 @@ export function SetPasswordForm({
|
|||||||
onClick={handleSubmit(submitRegister)}
|
onClick={handleSubmit(submitRegister)}
|
||||||
>
|
>
|
||||||
{loading && <Spinner className="h-5 w-5 mr-2" />}
|
{loading && <Spinner className="h-5 w-5 mr-2" />}
|
||||||
{t("password.submit")}
|
{t("set.submit")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ export async function sendPassword(command: UpdateSessionCommand) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function changePassword(command: {
|
export async function changePassword(command: {
|
||||||
code?: string;
|
code: string;
|
||||||
userId: string;
|
userId: string;
|
||||||
password: string;
|
password: string;
|
||||||
}) {
|
}) {
|
||||||
@@ -123,5 +123,5 @@ export async function changePassword(command: {
|
|||||||
}
|
}
|
||||||
const userId = user.userId;
|
const userId = user.userId;
|
||||||
|
|
||||||
return setPassword(userId, command.password);
|
return setPassword(userId, command.password, command.code);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import {
|
|||||||
} from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
|
} from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
|
||||||
import { PasswordComplexitySettingsSchema } from "@zitadel/proto/zitadel/settings/v2/password_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 type { RedirectURLsJson } from "@zitadel/proto/zitadel/user/v2/idp_pb";
|
||||||
|
import { NotificationType } from "@zitadel/proto/zitadel/user/v2/password_pb";
|
||||||
import {
|
import {
|
||||||
SearchQuery,
|
SearchQuery,
|
||||||
SearchQuerySchema,
|
SearchQuerySchema,
|
||||||
@@ -495,18 +496,32 @@ export async function passwordReset(userId: string) {
|
|||||||
return userService.passwordReset(
|
return userService.passwordReset(
|
||||||
{
|
{
|
||||||
userId,
|
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(
|
return userService.setPassword(
|
||||||
{
|
{
|
||||||
userId,
|
userId,
|
||||||
newPassword: {
|
newPassword: {
|
||||||
password,
|
password,
|
||||||
},
|
},
|
||||||
|
verification: {
|
||||||
|
case: "verificationCode",
|
||||||
|
value: code,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user