Skip to content

Commit 53a813b

Browse files
sniperwolfmromaszewiczclaude
authored
fix: improve email validation using net/mail package (#60)
* fix: improve email validation using net/mail package * fix: improve email validation using net/mail package * fix: update test expectations for email validation behavior change Invalid emails no longer persist their value after failed UnmarshalJSON validation, since the new net/mail-based validation sets the value only after successful parsing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Marcin Romaszewicz <marcinr@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 451d249 commit 53a813b

File tree

3 files changed

+14
-20
lines changed

3 files changed

+14
-20
lines changed

types/email.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package types
33
import (
44
"encoding/json"
55
"errors"
6+
"net/mail"
67
)
78

89
// ErrValidationEmail is the sentinel error returned when an email fails validation
@@ -14,11 +15,12 @@ var ErrValidationEmail = errors.New("email: failed to pass regex validation")
1415
type Email string
1516

1617
func (e Email) MarshalJSON() ([]byte, error) {
17-
if !emailRegex.MatchString(string(e)) {
18+
m, err := mail.ParseAddress(string(e))
19+
if err != nil {
1820
return nil, ErrValidationEmail
1921
}
2022

21-
return json.Marshal(string(e))
23+
return json.Marshal(m.Address)
2224
}
2325

2426
func (e *Email) UnmarshalJSON(data []byte) error {
@@ -31,10 +33,11 @@ func (e *Email) UnmarshalJSON(data []byte) error {
3133
return err
3234
}
3335

34-
*e = Email(s)
35-
if !emailRegex.MatchString(s) {
36+
m, err := mail.ParseAddress(s)
37+
if err != nil {
3638
return ErrValidationEmail
3739
}
3840

41+
*e = Email(m.Address)
3942
return nil
4043
}

types/email_test.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ func TestEmail_MarshalJSON_Validation(t *testing.T) {
2222
expectedJSON: []byte(`{"email":"validemail@openapicodegen.com"}`),
2323
expectedError: nil,
2424
},
25+
"it should succeed marshalling a valid email and return valid JSON populated with the email with valid separators": {
26+
email: Email("validemail+with_valid-separator{like}~these*ones@openapicodegen.com"),
27+
expectedJSON: []byte(`{"email":"validemail+with_valid-separator{like}~these*ones@openapicodegen.com"}`),
28+
expectedError: nil,
29+
},
2530
"it should fail marshalling an invalid email and return a validation error": {
2631
email: Email("invalidemail"),
2732
expectedJSON: nil,
@@ -71,10 +76,7 @@ func TestEmail_UnmarshalJSON_RequiredEmail_Validation(t *testing.T) {
7176
"it should fail validating an invalid email": {
7277
jsonStr: `{"email":"not-an-email"}`,
7378
expectedError: ErrValidationEmail,
74-
expectedEmail: func() Email {
75-
e := Email("not-an-email")
76-
return e
77-
}(),
79+
expectedEmail: Email(""),
7880
},
7981
"it should fail validating an empty email": {
8082
jsonStr: `{"email":""}`,
@@ -134,7 +136,7 @@ func TestEmail_UnmarshalJSON_NullableEmail_Validation(t *testing.T) {
134136
jsonStr: `{"email":"not-an-email"}`,
135137
expectedError: ErrValidationEmail,
136138
expectedEmail: func() *Email {
137-
e := Email("not-an-email")
139+
e := Email("")
138140
return &e
139141
}(),
140142
},

types/regexes.go

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)