zod icon indicating copy to clipboard operation
zod copied to clipboard

Email validation broken

Open timothyarmes opened this issue 1 year ago • 15 comments

Hi,

zod is rejecting valid email addresses of the form [email protected] (note the two dots after the @).

timothyarmes avatar May 03 '23 06:05 timothyarmes

Same here. And the email in question is actually used to send emails so definitely works. The actual email we are using is more like [email protected] where I replaced letters for other letters etc for privacy.

mauricedb avatar May 04 '23 06:05 mauricedb

#2157 (or #2274) should solve this. but not yet merged.

reminjp avatar May 09 '23 05:05 reminjp

Another example of a failing address: [email protected]. There's something about the number in ka1 that it doesn't like. Same with [email protected] and [email protected]

cullylarson avatar May 15 '23 22:05 cullylarson

Is this moving or is there a version that we can downgrade to fix this?

hkroger avatar May 16 '23 08:05 hkroger

Same for [email protected].

Dimrok avatar May 27 '23 06:05 Dimrok

To give more context, the current implementation favors speed over correctness.

// old version: too slow, didn't support unicode

// from https://stackoverflow.com/a/46181/1550155
// old version: too slow, didn't support unicode
// const emailRegex = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i;
//old email regex
// const emailRegex = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@((?!-)([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{1,})[^-<>()[\].,;:\s@"]$/i;
// eslint-disable-next-line
// const emailRegex =
//   /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\])|(\[IPv6:(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))\])|([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])*(\.[A-Za-z]{2,})+))$/;
// const emailRegex =
//   /^[a-zA-Z0-9\.\!\#\$\%\&\'\*\+\/\=\?\^\_\`\{\|\}\~\-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
// const emailRegex =
//   /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/i;
const emailRegex =
  /^([A-Z0-9_+-]+\.?)*[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i;
// const emailRegex =
//   /^[a-z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-z0-9-]+(?:\.[a-z0-9\-]+)*$/i;

For those who want correctness, a z.string().refine(...) with your chosen regex or validate.js should do the trick.

Dimrok avatar May 27 '23 06:05 Dimrok

When will a new release be cut with these changes? @colinhacks

adamwdennis avatar Jun 08 '23 19:06 adamwdennis

Hey, same issue here with [email protected] Have we any ETA for the new release ? Wanna try it 🙌

AlexandreBourdeaudhui avatar Jun 13 '23 17:06 AlexandreBourdeaudhui

Just got a report from the user that his email is not accepted. Format is [email protected]. It would be nice for this to be fixed ASAP.

paradox37 avatar Jun 28 '23 22:06 paradox37

Two emails I'm seeing that are failing and are both valid:

[email protected]
[email protected]

It's like it hates numbers

intellix avatar Jul 25 '23 18:07 intellix

Apostrophes in names are also broken, so if your name is eg O'Reilly and that's in your email address it now fails Zod validation.

micmcgrorty avatar Sep 26 '23 14:09 micmcgrorty

@colinhacks I believe this issue is now fixed and the issue can be closed. All of the examples provided in this thread are successfully parsed by Zod 3.22.4.

DavidTimms avatar Oct 14 '23 11:10 DavidTimms

@DavidTimms I'm still seeing the issue with apostrophes in 3.22.4

❯ grep version node_modules/zod/package.json
  "version": "3.22.4",
❯ node
Welcome to Node.js v21.5.0.
Type ".help" for more information.
> require('zod').z.string().url().parse("O'[email protected]")
Uncaught:
[
  {
    "validation": "url",
    "code": "invalid_string",
    "message": "Invalid url",
    "path": []
  }
]
    at get error [as error] (/path/to/node_modules/zod/lib/types.js:43:31)
    at ZodString.parse (/path/to/node_modules/zod/lib/types.js:143:22) {
  issues: [
    {
      validation: 'url',
      code: 'invalid_string',
      message: 'Invalid url',
      path: []
    }
  ],
  addIssue: [Function (anonymous)],
  addIssues: [Function (anonymous)],
  name: 'ZodError',
  errors: [
    {
      validation: 'url',
      code: 'invalid_string',
      message: 'Invalid url',
      path: []
    }
  ]
}

redbmk avatar Jan 29 '24 19:01 redbmk

For those wanting apostrophes to work, the patch is very simple and you can see it in my PR. In our application we've applied this via patch-package. One note is that depending on how you bundle if you go the patch-package route you might need to also patch the generated files as well. If you grep for emailRegex in your node_modules/zod you can see the 4 places it shows up.

I would love to get the PR merged here and not have to have the patch, if there is something else I need to do please let me know.

seanmacisaac avatar Feb 07 '24 01:02 seanmacisaac

A possibly related bug: Incorrectly formatted emails with multiple TLD 'dots' are incorrectly passing validation. For example, [email protected] passes validation, which it shouldn't due to .. between co and uk. I'm on version 3.20.5

willdspd avatar Feb 28 '24 13:02 willdspd

Danish/Swedish letters like ö or ø isn't accepted either. Those are valid to have in emails nowadays (90% sure about this). Example:
someemailwithø@gmail.com

Just want to put it out there. Lmk if I should create a new issue for this :-)

fuzzypawzz avatar May 16 '24 13:05 fuzzypawzz

I'm closing this since #2157 is the current final word on this. Nearly all the issues with dots and apostrophes have been resolved in Zod 3.22 or 3.23.

@fuzzypawzz Those characters aren't allowed in Gmail which is part of the rationale behind making Zod's email validation quite strict.

Screenshot 2024-05-16 at 1 12 23 PM

colinhacks avatar May 16 '24 20:05 colinhacks

@colinhacks Sorry for my bad example. It's correct that gmail doesn't allow those letters. However there are email providers that allows those special letters, and it's an issue in Nordic enterprises - you could argue that's it is not a major issue, however we (the corp im working for currently) are not able to use the email validator from Zod, instead we would have to build our own custom validators, because some users are indeed having email addresses with ø for example.

fuzzypawzz avatar May 17 '24 09:05 fuzzypawzz