From d2cabaebaba25657f052458de2ce6639b24ab4e8 Mon Sep 17 00:00:00 2001 From: Julien Tant <785518+JulienTant@users.noreply.github.com> Date: Sat, 5 Feb 2022 13:52:34 -0700 Subject: [PATCH] [MM-41343] Password reset must be 24hour (#19484) --- app/user.go | 8 ++++-- app/user_test.go | 69 ++++++++++++++++++++++++++++++------------------ 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/app/user.go b/app/user.go index 30fed41680..2d94355fdb 100644 --- a/app/user.go +++ b/app/user.go @@ -35,7 +35,7 @@ const ( TokenTypeTeamInvitation = "team_invitation" TokenTypeGuestInvitation = "guest_invitation" TokenTypeCWSAccess = "cws_access_token" - PasswordRecoverExpiryTime = 1000 * 60 * 60 // 1 hour + PasswordRecoverExpiryTime = 1000 * 60 * 60 * 24 // 24 hours InvitationExpiryTime = 1000 * 60 * 60 * 48 // 48 hours ImageProfilePixelDimension = 128 ) @@ -1266,11 +1266,15 @@ func (a *App) UpdateHashedPassword(user *model.User, newHashedPassword string) * } func (a *App) ResetPasswordFromToken(userSuppliedTokenString, newPassword string) *model.AppError { + return a.resetPasswordFromToken(userSuppliedTokenString, newPassword, model.GetMillis()) +} + +func (a *App) resetPasswordFromToken(userSuppliedTokenString, newPassword string, nowMilli int64) *model.AppError { token, err := a.GetPasswordRecoveryToken(userSuppliedTokenString) if err != nil { return err } - if model.GetMillis()-token.CreateAt >= PasswordRecoverExpiryTime { + if nowMilli-token.CreateAt >= PasswordRecoverExpiryTime { return model.NewAppError("resetPassword", "api.user.reset_password.link_expired.app_error", nil, "", http.StatusBadRequest) } diff --git a/app/user_test.go b/app/user_test.go index 443dde6b38..8d94f4b511 100644 --- a/app/user_test.go +++ b/app/user_test.go @@ -966,37 +966,56 @@ func TestPasswordRecovery(t *testing.T) { th := Setup(t).InitBasic() defer th.TearDown() - token, err := th.App.CreatePasswordRecoveryToken(th.BasicUser.Id, th.BasicUser.Email) - assert.Nil(t, err) + t.Run("password token with same email as during creation", func(t *testing.T) { + token, err := th.App.CreatePasswordRecoveryToken(th.BasicUser.Id, th.BasicUser.Email) + assert.Nil(t, err) - tokenData := struct { - UserId string - Email string - }{} + tokenData := struct { + UserId string + Email string + }{} - err2 := json.Unmarshal([]byte(token.Extra), &tokenData) - assert.NoError(t, err2) - assert.Equal(t, th.BasicUser.Id, tokenData.UserId) - assert.Equal(t, th.BasicUser.Email, tokenData.Email) + err2 := json.Unmarshal([]byte(token.Extra), &tokenData) + assert.NoError(t, err2) + assert.Equal(t, th.BasicUser.Id, tokenData.UserId) + assert.Equal(t, th.BasicUser.Email, tokenData.Email) - // Password token with same eMail as during creation - err = th.App.ResetPasswordFromToken(token.Token, "abcdefgh") - assert.Nil(t, err) - - // Password token with modified eMail after creation - token, err = th.App.CreatePasswordRecoveryToken(th.BasicUser.Id, th.BasicUser.Email) - assert.Nil(t, err) - - th.App.UpdateConfig(func(c *model.Config) { - *c.EmailSettings.RequireEmailVerification = false + err = th.App.ResetPasswordFromToken(token.Token, "abcdefgh") + assert.Nil(t, err) }) - th.BasicUser.Email = th.MakeEmail() - _, err = th.App.UpdateUser(th.BasicUser, false) - assert.Nil(t, err) + t.Run("password token with modified email as during creation", func(t *testing.T) { + token, err := th.App.CreatePasswordRecoveryToken(th.BasicUser.Id, th.BasicUser.Email) + assert.Nil(t, err) + + th.App.UpdateConfig(func(c *model.Config) { + *c.EmailSettings.RequireEmailVerification = false + }) + + th.BasicUser.Email = th.MakeEmail() + _, err = th.App.UpdateUser(th.BasicUser, false) + assert.Nil(t, err) + + err = th.App.ResetPasswordFromToken(token.Token, "abcdefgh") + assert.NotNil(t, err) + }) + + t.Run("non-expired token", func(t *testing.T) { + token, err := th.App.CreatePasswordRecoveryToken(th.BasicUser.Id, th.BasicUser.Email) + assert.Nil(t, err) + + err = th.App.resetPasswordFromToken(token.Token, "abcdefgh", model.GetMillis()) + assert.Nil(t, err) + }) + + t.Run("expired token", func(t *testing.T) { + token, err := th.App.CreatePasswordRecoveryToken(th.BasicUser.Id, th.BasicUser.Email) + assert.Nil(t, err) + + err = th.App.resetPasswordFromToken(token.Token, "abcdefgh", model.GetMillisForTime(time.Now().Add(25*time.Hour))) + assert.NotNil(t, err) + }) - err = th.App.ResetPasswordFromToken(token.Token, "abcdefgh") - assert.NotNil(t, err) } func TestGetViewUsersRestrictions(t *testing.T) {