24

How do I check for confirm password with zod?. I want to validate for confirm password with Zod. I want Zod to compare my password with comparePassword

export const registerUSerSchema = z.object({
    firstName: z.string(),
    lastName: z.string(),
    userName: z.string(),
    email: z.string().email(),
    phone: z.string().transform(data => Number(data)),
    password: z.string().min(4),
    confirmPassword: z.string().min(4),
    avatar: z.string().optional(),
    isVerified: z.boolean().optional()
})
Ushahemba Shir
  • 335
  • 1
  • 3
  • 12

3 Answers3

30

You can achieve this by tacking on a superRefine

export const registerUserSchema = z.object({
    firstName: z.string(),
    lastName: z.string(),
    userName: z.string(),
    email: z.string().email(),
    phone: z.string().transform(data => Number(data)),
    password: z.string().min(4),
    confirmPassword: z.string().min(4),
    avatar: z.string().optional(),
    isVerified: z.boolean().optional()
}).superRefine(({ confirmPassword, password }, ctx) => {
  if (confirmPassword !== password) {
    ctx.addIssue({
      code: "custom",
      message: "The passwords did not match"
    });
  }
});

If the passwords fail to parse for the base reason (not at least 4 characters) then that error will come through, but if the whole base object succeeds to parse, then the super refine check will happen.

Souperman
  • 5,057
  • 1
  • 14
  • 39
  • Okay. Thank you. Since I was using MVC, I decided to us `if statement` implement it in my controller logic. Incase of next time, I will follow this approach. `if (record.password != record.confirmPassword) { throw "Password and Confirm password didn't match"; }` – Ushahemba Shir Sep 14 '22 at 07:50
  • 14
    make sure you add `path: ['confirmPassword']` to the object passed in to the `addIssue` method if you want the error tied to that field – jrnxf Oct 03 '22 at 07:08
  • Make sure to add `path` as it provides a key for you to display the error message `ctx.addIssue({ code: 'custom', message: 'passwords do not match', path: ['confirm'], });` – Ejiro Asiuwhu Feb 23 '23 at 11:34
15

I have like this:

const validationSchema = z
    .object({
        name: string().min(1, { message: "Name is required" }), // pass custom message
        email: string().email(),
        website: string().optional(),
        country: string(),
        password: string(),
        confirm: string(),
    })
    .refine((data) => data.password === data.confirm, {
        message: "Passwords don't match",
        path: ["confirm"],
    });

I am using React Hook Form.

Here are some docs, I copy and pasted for you, so you can see how it works: https://docs.google.com/document/d/1jqTth88I-D0-qzq34B4sUGbp8wGmExS7kpc78QA_4sk/edit?usp=sharing

fruitloaf
  • 1,628
  • 15
  • 10
1

You can implement refine function like this:

const passwordForm = z
  .object({
    password: z.string(),
    confirmPassword: z.string(),
  })
  .refine((data) => data.password === data.confirmPassword, {
    message: "Passwords don't match",
    path: ["confirmPassword"], // path of error
  });

passwordForm.parse({ password: "asdf", confirmPassword: "qwer" });
Nguyễn Anh Tuấn
  • 1,023
  • 1
  • 12
  • 19