Skip to content

Commit cdaf68d

Browse files
authored
fix: not cleared field validation message (#2800)
1 parent 5ac7553 commit cdaf68d

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

selfservice/strategy/code/strategy_recovery.go

+2
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,8 @@ func (s *Strategy) Recover(w http.ResponseWriter, r *http.Request, f *recovery.F
278278

279279
sID := s.RecoveryStrategyID()
280280

281+
f.UI.ResetMessages()
282+
281283
// If the email is present in the submission body, the user needs a new code via resend
282284
if f.State != recovery.StateChooseMethod && len(body.Email) == 0 {
283285
if err := flow.MethodEnabledAndAllowed(ctx, sID, sID, s.deps); err != nil {

selfservice/strategy/code/strategy_recovery_test.go

+29-1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ func assertMessage(t *testing.T, body []byte, message string) {
5959
assert.Equal(t, message, gjson.GetBytes(body, "ui.messages.0.text").String())
6060
}
6161

62+
func assertFieldMessage(t *testing.T, body []byte, fieldName string, message string) {
63+
t.Helper()
64+
messages := gjson.GetBytes(body, "ui.nodes.#(attributes.name=="+fieldName+").messages")
65+
assert.Len(t, messages.Array(), 1, "expected field %s to have one message, got %s", fieldName, messages)
66+
assert.Equal(t, message, messages.Get("0.text").String())
67+
}
68+
6269
func extractCsrfToken(body []byte) string {
6370
return gjson.GetBytes(body, "ui.nodes.#(attributes.name==csrf_token).attributes.value").String()
6471
}
@@ -935,9 +942,30 @@ func TestRecovery(t *testing.T) {
935942
// For good measure, check that the second code works!
936943
body = submitRecoveryCode(t, c, body, RecoveryFlowTypeBrowser, recoveryCode2, http.StatusOK)
937944
assertMessage(t, []byte(body), "You successfully recovered your account. Please change your password or set up an alternative login method (e.g. social sign in) within the next 60.00 minutes.")
938-
939945
})
940946

947+
t.Run("description=should not show outdated validation message if newer message appears #2799", func(t *testing.T) {
948+
recoveryEmail := strings.ToLower(testhelpers.RandomEmail())
949+
createIdentityToRecover(t, reg, recoveryEmail)
950+
951+
c := testhelpers.NewClientWithCookies(t)
952+
body := expectSuccessfulRecovery(t, c, RecoveryFlowTypeBrowser, func(v url.Values) {
953+
v.Set("email", recoveryEmail)
954+
})
955+
956+
action := gjson.Get(body, "ui.action").String()
957+
require.NotEmpty(t, action)
958+
assert.Equal(t, recoveryEmail, gjson.Get(body, "ui.nodes.#(attributes.name==email).attributes.value").String())
959+
960+
body = submitRecoveryCode(t, c, body, RecoveryFlowTypeBrowser, "123", http.StatusOK) // Send code that validates field schema
961+
962+
assertFieldMessage(t, []byte(body), "code", "does not match pattern \"^\\\\d{8}$\"")
963+
964+
body = submitRecoveryCode(t, c, body, RecoveryFlowTypeBrowser, "12312312", http.StatusOK) // Now send a wrong code that triggers "global" validation error
965+
966+
assert.Empty(t, gjson.Get(body, "ui.nodes.#(attributes.name==code).messages").Array())
967+
assertMessage(t, []byte(body), "The recovery code is invalid or has already been used. Please try again.")
968+
})
941969
}
942970

943971
func TestDisabledStrategy(t *testing.T) {

0 commit comments

Comments
 (0)