From 24dcf2a44ad1e39bf28f13dceba80ba5b48b8e59 Mon Sep 17 00:00:00 2001 From: Fabrizio Fallico Date: Tue, 4 Feb 2025 18:25:57 +0100 Subject: [PATCH 1/2] fix: improve email validation using net/mail package --- types/email.go | 5 +++-- types/email_test.go | 5 +++++ types/regexes.go | 11 ----------- 3 files changed, 8 insertions(+), 13 deletions(-) delete mode 100644 types/regexes.go diff --git a/types/email.go b/types/email.go index e4a1cbda..16d78eae 100644 --- a/types/email.go +++ b/types/email.go @@ -3,6 +3,7 @@ package types import ( "encoding/json" "errors" + "net/mail" ) // ErrValidationEmail is the sentinel error returned when an email fails validation @@ -14,7 +15,7 @@ var ErrValidationEmail = errors.New("email: failed to pass regex validation") type Email string func (e Email) MarshalJSON() ([]byte, error) { - if !emailRegex.MatchString(string(e)) { + if _, err := mail.ParseAddress(string(e)); err != nil { return nil, ErrValidationEmail } @@ -32,7 +33,7 @@ func (e *Email) UnmarshalJSON(data []byte) error { } *e = Email(s) - if !emailRegex.MatchString(s) { + if _, err := mail.ParseAddress(s); err != nil { return ErrValidationEmail } diff --git a/types/email_test.go b/types/email_test.go index 736056b1..f89787cd 100644 --- a/types/email_test.go +++ b/types/email_test.go @@ -22,6 +22,11 @@ func TestEmail_MarshalJSON_Validation(t *testing.T) { expectedJSON: []byte(`{"email":"validemail@openapicodegen.com"}`), expectedError: nil, }, + "it should succeed marshalling a valid email and return valid JSON populated with the email with valid separators": { + email: Email("validemail+with_valid-separator{like}~these*ones@openapicodegen.com"), + expectedJSON: []byte(`{"email":"validemail+with_valid-separator{like}~these*ones@openapicodegen.com"}`), + expectedError: nil, + }, "it should fail marshalling an invalid email and return a validation error": { email: Email("invalidemail"), expectedJSON: nil, diff --git a/types/regexes.go b/types/regexes.go deleted file mode 100644 index 94f17df5..00000000 --- a/types/regexes.go +++ /dev/null @@ -1,11 +0,0 @@ -package types - -import "regexp" - -const ( - emailRegexString = "^(?:(?:(?:(?:[a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(?:\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|(?:(?:\\x22)(?:(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(?:\\x20|\\x09)+)?(?:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(\\x20|\\x09)+)?(?:\\x22))))@(?:(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$" -) - -var ( - emailRegex = regexp.MustCompile(emailRegexString) -) From 05b0be10b4069d6428f38f79858622963e110221 Mon Sep 17 00:00:00 2001 From: Fabrizio Fallico Date: Wed, 5 Feb 2025 09:24:55 +0100 Subject: [PATCH 2/2] fix: improve email validation using net/mail package --- types/email.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/types/email.go b/types/email.go index 16d78eae..234e7ccf 100644 --- a/types/email.go +++ b/types/email.go @@ -15,11 +15,12 @@ var ErrValidationEmail = errors.New("email: failed to pass regex validation") type Email string func (e Email) MarshalJSON() ([]byte, error) { - if _, err := mail.ParseAddress(string(e)); err != nil { + m, err := mail.ParseAddress(string(e)) + if err != nil { return nil, ErrValidationEmail } - return json.Marshal(string(e)) + return json.Marshal(m.Address) } func (e *Email) UnmarshalJSON(data []byte) error { @@ -32,10 +33,11 @@ func (e *Email) UnmarshalJSON(data []byte) error { return err } - *e = Email(s) - if _, err := mail.ParseAddress(s); err != nil { + m, err := mail.ParseAddress(s) + if err != nil { return ErrValidationEmail } + *e = Email(m.Address) return nil }