From 960a4f94f5500e33a0ec2f6afe0380bbc9562500 Mon Sep 17 00:00:00 2001 From: Stojan Dimitrovski Date: Tue, 19 Mar 2024 15:29:26 +0700 Subject: [PATCH] fix: invalidate email, phone OTPs on password change (#1489) Password change may mean that the user no longer trusts the actions performed by the previous "knower" of the password, so all password reset, email confirmation, phone confirmation OTPs should be reset. --- internal/api/user_test.go | 2 +- internal/models/user.go | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/internal/api/user_test.go b/internal/api/user_test.go index 18ed6ec85..0fd0ac294 100644 --- a/internal/api/user_test.go +++ b/internal/api/user_test.go @@ -371,7 +371,7 @@ func (ts *UserTestSuite) TestUserUpdatePasswordReauthentication() { require.True(ts.T(), u.Authenticate(context.Background(), "newpass")) require.Empty(ts.T(), u.ReauthenticationToken) - require.NotEmpty(ts.T(), u.ReauthenticationSentAt) + require.Nil(ts.T(), u.ReauthenticationSentAt) } func (ts *UserTestSuite) TestUserUpdatePasswordLogoutOtherSessions() { diff --git a/internal/models/user.go b/internal/models/user.go index 105c57a9c..be70b13ba 100644 --- a/internal/models/user.go +++ b/internal/models/user.go @@ -301,7 +301,20 @@ func (u *User) SetPassword(ctx context.Context, password string) error { // UpdatePassword updates the user's password. Use SetPassword outside of a transaction first! func (u *User) UpdatePassword(tx *storage.Connection, sessionID *uuid.UUID) error { - if err := tx.UpdateOnly(u, "encrypted_password"); err != nil { + // These need to be reset because password change may mean the user no longer trusts the actions performed by the previous password. + u.ConfirmationToken = "" + u.ConfirmationSentAt = nil + u.RecoveryToken = "" + u.RecoverySentAt = nil + u.EmailChangeTokenCurrent = "" + u.EmailChangeTokenNew = "" + u.EmailChangeSentAt = nil + u.PhoneChangeToken = "" + u.PhoneChangeSentAt = nil + u.ReauthenticationToken = "" + u.ReauthenticationSentAt = nil + + if err := tx.UpdateOnly(u, "encrypted_password", "confirmation_token", "confirmation_sent_at", "recovery_token", "recovery_sent_at", "email_change_token_current", "email_change_token_new", "email_change_sent_at", "phone_change_token", "phone_change_sent_at", "reauthentication_token", "reauthentication_sent_at"); err != nil { return err }