Skip to content

Commit

Permalink
Merge pull request #354 from justin-wilxite/totp-fix
Browse files Browse the repository at this point in the history
Handle invalid recovery code in totp2fa #351
  • Loading branch information
aarondl committed Sep 28, 2023
2 parents d38273a + ee0d69a commit dbfe07e
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 0 deletions.
27 changes: 27 additions & 0 deletions otp/twofactor/sms2fa/sms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,33 @@ func TestValidatorPostOk(t *testing.T) {
}
})

t.Run("InvalidRecovery", func(t *testing.T) {
h := testSetup()
r, w, _ := h.newHTTP("POST")
v := &SMSValidator{SMS: h.sms, Page: PageSMSValidate}

user := &mocks.User{Email: "test@test.com", SMSPhoneNumber: "number"}
h.storer.Users[user.Email] = user
h.setSession(authboss.SessionKey, user.Email)

h.setSession(SessionSMSSecret, "code-user-never-got")
h.bodyReader.Return = mocks.Values{Recovery: "INVALID"}

h.loadClientState(w, &r)

if err := v.Post(w, r); err != nil {
t.Fatal(err)
}

// Flush client state
w.WriteHeader(http.StatusOK)

validation := h.responder.Data[authboss.DataValidation].(map[string][]string)
if got := validation[FormValueCode][0]; got != "2fa code was invalid" {
t.Error("data wrong:", got)
}
})

t.Run("FailRemoveCode", func(t *testing.T) {
h := testSetup()
r, w, _ := h.newHTTP("POST")
Expand Down
2 changes: 2 additions & 0 deletions otp/twofactor/totp2fa/totp.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,8 @@ func (t *TOTP) validate(r *http.Request) (User, string, error) {
if err := t.Authboss.Config.Storage.Server.Save(r.Context(), user); err != nil {
return nil, "", err
}
} else {
return user, validationErrInvalidCode, nil
}

return user, validationSuccess, nil
Expand Down
28 changes: 28 additions & 0 deletions otp/twofactor/totp2fa/totp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,34 @@ func TestPostValidate(t *testing.T) {
t.Error("path wrong:", opts.RedirectPath)
}
})

t.Run("InvalidRecovery", func(t *testing.T) {
h := testSetup()

r, w, _ := h.newHTTP("POST")
user := setupMore(h)
secret := makeSecretKey(h, user.Email)
user.TOTPSecretKey = secret

// User inputs invalid recovery code
h.bodyReader.Return = mocks.Values{Recovery: "INVALID"}

h.setSession(SessionTOTPPendingPID, user.Email)
h.setSession(SessionTOTPSecret, "secret")
h.setSession(authboss.SessionHalfAuthKey, "true")
h.loadClientState(w, &r)

if err := h.totp.PostValidate(w, r); err != nil {
t.Error(err)
}

// Flush client state
w.WriteHeader(http.StatusOK)

if got := h.responder.Data[authboss.DataValidation].(map[string][]string); got[FormValueCode][0] != "2fa code was invalid" {
t.Error("data wrong:", got)
}
})
}

func makeSecretKey(h *testHarness, email string) string {
Expand Down

0 comments on commit dbfe07e

Please sign in to comment.