mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-23 07:52:15 +00:00
fix(login): use onChange instead of onBlur with react-hook-form (#11354)
# Which Problems Are Solved Fixes a problem where submit buttons where not correctly enabled onBlur event # How the Problems Are Solved By changing the react-hook-form mode property to onChange, buttons are enabled as intended
This commit is contained in:
@@ -1,15 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
lowerCaseValidator,
|
||||
numberValidator,
|
||||
symbolValidator,
|
||||
upperCaseValidator,
|
||||
} from "@/helpers/validators";
|
||||
import {
|
||||
checkSessionAndSetPassword,
|
||||
sendPassword,
|
||||
} from "@/lib/server/password";
|
||||
import { lowerCaseValidator, numberValidator, symbolValidator, upperCaseValidator } from "@/helpers/validators";
|
||||
import { checkSessionAndSetPassword, sendPassword } from "@/lib/server/password";
|
||||
import { create } from "@zitadel/client";
|
||||
import { ChecksSchema } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
|
||||
import { PasswordComplexitySettings } from "@zitadel/proto/zitadel/settings/v2/password_settings_pb";
|
||||
@@ -40,17 +32,11 @@ type Props = {
|
||||
organization?: string;
|
||||
};
|
||||
|
||||
export function ChangePasswordForm({
|
||||
passwordComplexitySettings,
|
||||
sessionId,
|
||||
loginName,
|
||||
requestId,
|
||||
organization,
|
||||
}: Props) {
|
||||
export function ChangePasswordForm({ passwordComplexitySettings, sessionId, loginName, requestId, organization }: Props) {
|
||||
const router = useRouter();
|
||||
|
||||
const { register, handleSubmit, watch, formState } = useForm<Inputs>({
|
||||
mode: "onBlur",
|
||||
mode: "onChange",
|
||||
defaultValues: {
|
||||
password: "",
|
||||
comfirmPassword: "",
|
||||
@@ -78,11 +64,7 @@ export function ChangePasswordForm({
|
||||
});
|
||||
|
||||
if (changeResponse && "error" in changeResponse && changeResponse.error) {
|
||||
setError(
|
||||
typeof changeResponse.error === "string"
|
||||
? changeResponse.error
|
||||
: t("change.errors.unknownError")
|
||||
);
|
||||
setError(typeof changeResponse.error === "string" ? changeResponse.error : t("change.errors.unknownError"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -109,20 +91,12 @@ export function ChangePasswordForm({
|
||||
setLoading(false);
|
||||
});
|
||||
|
||||
if (
|
||||
passwordResponse &&
|
||||
"error" in passwordResponse &&
|
||||
passwordResponse.error
|
||||
) {
|
||||
if (passwordResponse && "error" in passwordResponse && passwordResponse.error) {
|
||||
setError(passwordResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
passwordResponse &&
|
||||
"redirect" in passwordResponse &&
|
||||
passwordResponse.redirect
|
||||
) {
|
||||
if (passwordResponse && "redirect" in passwordResponse && passwordResponse.redirect) {
|
||||
return router.push(passwordResponse.redirect);
|
||||
}
|
||||
|
||||
@@ -134,9 +108,7 @@ export function ChangePasswordForm({
|
||||
const watchPassword = watch("password", "");
|
||||
const watchConfirmPassword = watch("confirmPassword", "");
|
||||
|
||||
const hasMinLength =
|
||||
passwordComplexitySettings &&
|
||||
watchPassword?.length >= passwordComplexitySettings.minLength;
|
||||
const hasMinLength = passwordComplexitySettings && watchPassword?.length >= passwordComplexitySettings.minLength;
|
||||
const hasSymbol = symbolValidator(watchPassword);
|
||||
const hasNumber = numberValidator(watchPassword);
|
||||
const hasUppercase = upperCaseValidator(watchPassword);
|
||||
@@ -196,17 +168,11 @@ export function ChangePasswordForm({
|
||||
<Button
|
||||
type="submit"
|
||||
variant={ButtonVariants.Primary}
|
||||
disabled={
|
||||
loading ||
|
||||
!policyIsValid ||
|
||||
!formState.isValid ||
|
||||
watchPassword !== watchConfirmPassword
|
||||
}
|
||||
disabled={loading || !policyIsValid || !formState.isValid || watchPassword !== watchConfirmPassword}
|
||||
onClick={handleSubmit(submitChange)}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}{" "}
|
||||
<Translated i18nKey="change.submit" namespace="password" />
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />} <Translated i18nKey="change.submit" namespace="password" />
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -20,7 +20,7 @@ export function DeviceCodeForm({ userCode }: { userCode?: string }) {
|
||||
const router = useRouter();
|
||||
|
||||
const { register, handleSubmit, formState } = useForm<Inputs>({
|
||||
mode: "onBlur",
|
||||
mode: "onChange",
|
||||
defaultValues: {
|
||||
userCode: userCode || "",
|
||||
},
|
||||
@@ -88,8 +88,7 @@ export function DeviceCodeForm({ userCode }: { userCode?: string }) {
|
||||
onClick={handleSubmit(submitCodeAndContinue)}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}{" "}
|
||||
<Translated i18nKey="usercode.submit" namespace="device" />
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />} <Translated i18nKey="usercode.submit" namespace="device" />
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -24,7 +24,7 @@ type Props = {
|
||||
|
||||
export function LDAPUsernamePasswordForm({ idpId, link }: Props) {
|
||||
const { register, handleSubmit, formState } = useForm<Inputs>({
|
||||
mode: "onBlur",
|
||||
mode: "onChange",
|
||||
});
|
||||
|
||||
const t = useTranslations("ldap");
|
||||
|
||||
@@ -44,7 +44,7 @@ export function LoginOTP({ host, loginName, sessionId, requestId, organization,
|
||||
const initialized = useRef(false);
|
||||
|
||||
const { register, handleSubmit, formState } = useForm<Inputs>({
|
||||
mode: "onBlur",
|
||||
mode: "onChange",
|
||||
defaultValues: {
|
||||
code: code ? code : "",
|
||||
},
|
||||
|
||||
@@ -28,7 +28,7 @@ type Props = {
|
||||
|
||||
export function PasswordForm({ loginSettings, loginName, organization, requestId }: Props) {
|
||||
const { register, handleSubmit, formState } = useForm<Inputs>({
|
||||
mode: "onBlur",
|
||||
mode: "onChange",
|
||||
});
|
||||
|
||||
const t = useTranslations("password");
|
||||
|
||||
@@ -47,7 +47,7 @@ export function RegisterFormIDPIncomplete({
|
||||
idpUserName,
|
||||
}: Props) {
|
||||
const { register, handleSubmit, formState } = useForm<Inputs>({
|
||||
mode: "onBlur",
|
||||
mode: "onChange",
|
||||
defaultValues: {
|
||||
email: defaultValues?.email ?? "",
|
||||
firstname: defaultValues?.firstname ?? "",
|
||||
|
||||
@@ -46,7 +46,7 @@ export function RegisterForm({
|
||||
idpCount = 0,
|
||||
}: Props) {
|
||||
const { register, handleSubmit, formState } = useForm<Inputs>({
|
||||
mode: "onBlur",
|
||||
mode: "onChange",
|
||||
defaultValues: {
|
||||
email: email ?? "",
|
||||
firstName: firstname ?? "",
|
||||
|
||||
@@ -25,7 +25,7 @@ type Props = {
|
||||
|
||||
export function RegisterPasskey({ sessionId, userId, isPrompt, organization, requestId, code, codeId }: Props) {
|
||||
const { handleSubmit, formState } = useForm<Inputs>({
|
||||
mode: "onBlur",
|
||||
mode: "onChange",
|
||||
});
|
||||
|
||||
const [error, setError] = useState<string>("");
|
||||
|
||||
@@ -1,16 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
lowerCaseValidator,
|
||||
numberValidator,
|
||||
symbolValidator,
|
||||
upperCaseValidator,
|
||||
} from "@/helpers/validators";
|
||||
import {
|
||||
changePassword,
|
||||
resetPassword,
|
||||
sendPassword,
|
||||
} from "@/lib/server/password";
|
||||
import { lowerCaseValidator, numberValidator, symbolValidator, upperCaseValidator } from "@/helpers/validators";
|
||||
import { changePassword, resetPassword, sendPassword } from "@/lib/server/password";
|
||||
import { create } from "@zitadel/client";
|
||||
import { ChecksSchema } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
|
||||
import { PasswordComplexitySettings } from "@zitadel/proto/zitadel/settings/v2/password_settings_pb";
|
||||
@@ -54,7 +45,7 @@ export function SetPasswordForm({
|
||||
codeRequired,
|
||||
}: Props) {
|
||||
const { register, handleSubmit, watch, formState } = useForm<Inputs>({
|
||||
mode: "onBlur",
|
||||
mode: "onChange",
|
||||
defaultValues: {
|
||||
code: code ?? "",
|
||||
},
|
||||
@@ -148,20 +139,12 @@ export function SetPasswordForm({
|
||||
setLoading(false);
|
||||
});
|
||||
|
||||
if (
|
||||
passwordResponse &&
|
||||
"error" in passwordResponse &&
|
||||
passwordResponse.error
|
||||
) {
|
||||
if (passwordResponse && "error" in passwordResponse && passwordResponse.error) {
|
||||
setError(passwordResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
passwordResponse &&
|
||||
"redirect" in passwordResponse &&
|
||||
passwordResponse.redirect
|
||||
) {
|
||||
if (passwordResponse && "redirect" in passwordResponse && passwordResponse.redirect) {
|
||||
return router.push(passwordResponse.redirect);
|
||||
}
|
||||
|
||||
@@ -173,9 +156,7 @@ export function SetPasswordForm({
|
||||
const watchPassword = watch("password", "");
|
||||
const watchConfirmPassword = watch("confirmPassword", "");
|
||||
|
||||
const hasMinLength =
|
||||
passwordComplexitySettings &&
|
||||
watchPassword?.length >= passwordComplexitySettings.minLength;
|
||||
const hasMinLength = passwordComplexitySettings && watchPassword?.length >= passwordComplexitySettings.minLength;
|
||||
const hasSymbol = symbolValidator(watchPassword);
|
||||
const hasNumber = numberValidator(watchPassword);
|
||||
const hasUppercase = upperCaseValidator(watchPassword);
|
||||
@@ -271,17 +252,11 @@ export function SetPasswordForm({
|
||||
<Button
|
||||
type="submit"
|
||||
variant={ButtonVariants.Primary}
|
||||
disabled={
|
||||
loading ||
|
||||
!policyIsValid ||
|
||||
!formState.isValid ||
|
||||
watchPassword !== watchConfirmPassword
|
||||
}
|
||||
disabled={loading || !policyIsValid || !formState.isValid || watchPassword !== watchConfirmPassword}
|
||||
onClick={handleSubmit(submitPassword)}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}{" "}
|
||||
<Translated i18nKey="set.submit" namespace="password" />
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />} <Translated i18nKey="set.submit" namespace="password" />
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
lowerCaseValidator,
|
||||
numberValidator,
|
||||
symbolValidator,
|
||||
upperCaseValidator,
|
||||
} from "@/helpers/validators";
|
||||
import { lowerCaseValidator, numberValidator, symbolValidator, upperCaseValidator } from "@/helpers/validators";
|
||||
import { registerUser } from "@/lib/server/register";
|
||||
import { PasswordComplexitySettings } from "@zitadel/proto/zitadel/settings/v2/password_settings_pb";
|
||||
import { useRouter } from "next/navigation";
|
||||
@@ -45,7 +40,7 @@ export function SetRegisterPasswordForm({
|
||||
requestId,
|
||||
}: Props) {
|
||||
const { register, handleSubmit, watch, formState } = useForm<Inputs>({
|
||||
mode: "onBlur",
|
||||
mode: "onChange",
|
||||
defaultValues: {
|
||||
email: email ?? "",
|
||||
firstname: firstname ?? "",
|
||||
@@ -93,9 +88,7 @@ export function SetRegisterPasswordForm({
|
||||
const watchPassword = watch("password", "");
|
||||
const watchConfirmPassword = watch("confirmPassword", "");
|
||||
|
||||
const hasMinLength =
|
||||
passwordComplexitySettings &&
|
||||
watchPassword?.length >= passwordComplexitySettings.minLength;
|
||||
const hasMinLength = passwordComplexitySettings && watchPassword?.length >= passwordComplexitySettings.minLength;
|
||||
const hasSymbol = symbolValidator(watchPassword);
|
||||
const hasNumber = numberValidator(watchPassword);
|
||||
const hasUppercase = upperCaseValidator(watchPassword);
|
||||
@@ -155,17 +148,11 @@ export function SetRegisterPasswordForm({
|
||||
<Button
|
||||
type="submit"
|
||||
variant={ButtonVariants.Primary}
|
||||
disabled={
|
||||
loading ||
|
||||
!policyIsValid ||
|
||||
!formState.isValid ||
|
||||
watchPassword !== watchConfirmPassword
|
||||
}
|
||||
disabled={loading || !policyIsValid || !formState.isValid || watchPassword !== watchConfirmPassword}
|
||||
onClick={handleSubmit(submitRegister)}
|
||||
data-testid="submit-button"
|
||||
>
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />}{" "}
|
||||
<Translated i18nKey="password.submit" namespace="register" />
|
||||
{loading && <Spinner className="mr-2 h-5 w-5" />} <Translated i18nKey="password.submit" namespace="register" />
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -36,7 +36,7 @@ export function TotpRegister({ uri, loginName, sessionId, requestId, organizatio
|
||||
const router = useRouter();
|
||||
|
||||
const { register, handleSubmit, formState } = useForm<Inputs>({
|
||||
mode: "onBlur",
|
||||
mode: "onChange",
|
||||
defaultValues: {
|
||||
code: "",
|
||||
},
|
||||
|
||||
@@ -27,17 +27,9 @@ type Props = {
|
||||
allowRegister: boolean;
|
||||
};
|
||||
|
||||
export function UsernameForm({
|
||||
loginName,
|
||||
requestId,
|
||||
organization,
|
||||
suffix,
|
||||
loginSettings,
|
||||
submit,
|
||||
allowRegister,
|
||||
}: Props) {
|
||||
export function UsernameForm({ loginName, requestId, organization, suffix, loginSettings, submit, allowRegister }: Props) {
|
||||
const { register, handleSubmit, formState } = useForm<Inputs>({
|
||||
mode: "onBlur",
|
||||
mode: "onChange",
|
||||
defaultValues: {
|
||||
loginName: loginName ? loginName : "",
|
||||
},
|
||||
@@ -87,10 +79,7 @@ export function UsernameForm({
|
||||
}, []);
|
||||
|
||||
let inputLabel = t("labels.loginname");
|
||||
if (
|
||||
loginSettings?.disableLoginWithEmail &&
|
||||
loginSettings?.disableLoginWithPhone
|
||||
) {
|
||||
if (loginSettings?.disableLoginWithEmail && loginSettings?.disableLoginWithPhone) {
|
||||
inputLabel = t("labels.username");
|
||||
} else if (loginSettings?.disableLoginWithEmail) {
|
||||
inputLabel = t("labels.usernameOrPhoneNumber");
|
||||
|
||||
@@ -25,18 +25,11 @@ type Props = {
|
||||
requestId?: string;
|
||||
};
|
||||
|
||||
export function VerifyForm({
|
||||
userId,
|
||||
loginName,
|
||||
organization,
|
||||
requestId,
|
||||
code,
|
||||
isInvite,
|
||||
}: Props) {
|
||||
export function VerifyForm({ userId, loginName, organization, requestId, code, isInvite }: Props) {
|
||||
const router = useRouter();
|
||||
|
||||
const { register, handleSubmit, formState } = useForm<Inputs>({
|
||||
mode: "onBlur",
|
||||
mode: "onChange",
|
||||
defaultValues: {
|
||||
code: code ?? "",
|
||||
},
|
||||
@@ -73,9 +66,7 @@ export function VerifyForm({
|
||||
}
|
||||
|
||||
const fcn = useCallback(
|
||||
async function submitCodeAndContinue(
|
||||
value: Inputs,
|
||||
): Promise<boolean | void> {
|
||||
async function submitCodeAndContinue(value: Inputs): Promise<boolean | void> {
|
||||
setLoading(true);
|
||||
|
||||
const response = await sendVerification({
|
||||
|
||||
Reference in New Issue
Block a user