Skip to content

Commit 1e6bf6d

Browse files
authored
Merge pull request #41 from privacybydesign/case-insensitive-verify
Make verify API email case-insensitive
2 parents cf5c50b + e5486ac commit 1e6bf6d

2 files changed

Lines changed: 30 additions & 3 deletions

File tree

backend/internal/http/handlers.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,14 @@ func (a *API) handleVerifyDone(w http.ResponseWriter, r *http.Request) {
5959
return
6060
}
6161

62-
remove_err := a.tokenStorage.RemoveToken(req.Email)
62+
validator := validators.EmailValidator{}
63+
valid, parsedAddress, errCode := validator.ParseAndValidateEmailAddress(req.Email)
64+
if !valid {
65+
writeError(w, http.StatusBadRequest, *errCode)
66+
return
67+
}
68+
69+
remove_err := a.tokenStorage.RemoveToken(*parsedAddress)
6370
if remove_err != nil {
6471
writeError(w, http.StatusInternalServerError, "error_removing_token")
6572
return
@@ -78,11 +85,19 @@ func (a *API) handleVerifyEmail(w http.ResponseWriter, r *http.Request) {
7885
writeError(w, http.StatusBadRequest, "token_or_email_required")
7986
return
8087
}
88+
// Validate and normalize the email address
89+
validator := validators.EmailValidator{}
90+
valid, parsedAddress, errCode := validator.ParseAndValidateEmailAddress(req.Email)
91+
if !valid {
92+
writeError(w, http.StatusBadRequest, *errCode)
93+
return
94+
}
95+
8196
if a.tokenStorage == nil {
8297
http.Error(w, "token generator not configured", http.StatusInternalServerError)
8398
return
8499
}
85-
expectedToken, retrieve_err := a.tokenStorage.RetrieveToken(req.Email)
100+
expectedToken, retrieve_err := a.tokenStorage.RetrieveToken(*parsedAddress)
86101
if retrieve_err != nil {
87102
writeError(w, http.StatusBadRequest, "error_token_invalid")
88103
return
@@ -99,7 +114,7 @@ func (a *API) handleVerifyEmail(w http.ResponseWriter, r *http.Request) {
99114
return
100115
}
101116

102-
jwt, create_err := jwtCreator.CreateJwt(req.Email)
117+
jwt, create_err := jwtCreator.CreateJwt(*parsedAddress)
103118
if create_err != nil {
104119
writeError(w, http.StatusInternalServerError, "jwt_creation_error")
105120
return

backend/tests/integration_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,18 @@ func TestSendEmailHappyPath(t *testing.T) {
138138
}
139139

140140
}
141+
func TestSendAndVerifyWithUppercaseEmail(t *testing.T) {
142+
uppercaseEmail := "Test@Email.Com"
143+
144+
resp := makeSendEmailRequest(t, uppercaseEmail, "en")
145+
require.Equal(t, http.StatusOK, resp.StatusCode)
146+
147+
// Verify using the same uppercase email — should match via normalization
148+
res := makeVerifyEmailRequest(t, testToken, uppercaseEmail)
149+
resBody := readResponseBody(t, res)
150+
require.Equalf(t, http.StatusOK, res.StatusCode, "body: %v", resBody)
151+
}
152+
141153
func TestSendEmailEmptyData(t *testing.T) {
142154

143155
res := makeSendEmailRequest(t, "", "en")

0 commit comments

Comments
 (0)