()
| 149 | } |
| 150 | |
| 151 | func (ts *VerifyTestSuite) TestVerifySecureEmailChange() { |
| 152 | currentEmail := "test@example.com" |
| 153 | newEmail := "new@example.com" |
| 154 | |
| 155 | // Change from new email to current email and back to new email |
| 156 | cases := []struct { |
| 157 | desc string |
| 158 | body map[string]interface{} |
| 159 | isPKCE bool |
| 160 | currentEmail string |
| 161 | newEmail string |
| 162 | }{ |
| 163 | { |
| 164 | desc: "Implict Flow Email Change", |
| 165 | body: map[string]interface{}{ |
| 166 | "email": newEmail, |
| 167 | }, |
| 168 | isPKCE: false, |
| 169 | currentEmail: currentEmail, |
| 170 | newEmail: newEmail, |
| 171 | }, |
| 172 | { |
| 173 | desc: "PKCE Email Change", |
| 174 | body: map[string]interface{}{ |
| 175 | "email": currentEmail, |
| 176 | // Code Challenge needs to be at least 43 characters long |
| 177 | "code_challenge": "6b151854-cc15-4e29-8db7-3d3a9f15b3066b151854-cc15-4e29-8db7-3d3a9f15b306", |
| 178 | "code_challenge_method": models.SHA256.String(), |
| 179 | }, |
| 180 | isPKCE: true, |
| 181 | currentEmail: newEmail, |
| 182 | newEmail: currentEmail, |
| 183 | }, |
| 184 | } |
| 185 | |
| 186 | for _, c := range cases { |
| 187 | ts.Run(c.desc, func() { |
| 188 | u, err := models.FindUserByEmailAndAudience(ts.API.db, c.currentEmail, ts.Config.JWT.Aud) |
| 189 | require.NoError(ts.T(), err) |
| 190 | |
| 191 | // reset user |
| 192 | u.EmailChangeSentAt = nil |
| 193 | u.EmailChangeTokenCurrent = "" |
| 194 | u.EmailChangeTokenNew = "" |
| 195 | require.NoError(ts.T(), ts.API.db.Update(u)) |
| 196 | require.NoError(ts.T(), models.ClearAllOneTimeTokensForUser(ts.API.db, u.ID)) |
| 197 | |
| 198 | // Request body |
| 199 | var buffer bytes.Buffer |
| 200 | require.NoError(ts.T(), json.NewEncoder(&buffer).Encode(c.body)) |
| 201 | |
| 202 | // Setup request |
| 203 | req := httptest.NewRequest(http.MethodPut, "http://localhost/user", &buffer) |
| 204 | req.Header.Set("Content-Type", "application/json") |
| 205 | |
| 206 | // Generate access token for request and a mock session |
| 207 | var token string |
| 208 | session, err := models.NewSession(u.ID, nil) |
nothing calls this directly
no test coverage detected