From 2d519569d7b8540886d0a64bf3e561ef5f91eb63 Mon Sep 17 00:00:00 2001 From: Kang Ming Date: Mon, 26 Aug 2024 00:08:04 -0400 Subject: [PATCH] fix: allow anonymous user to update password (#1739) --- internal/api/anonymous_test.go | 29 +++++++++++++++++++++++++---- internal/api/user.go | 9 ++++----- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/internal/api/anonymous_test.go b/internal/api/anonymous_test.go index 6ab2bae04..81d900de8 100644 --- a/internal/api/anonymous_test.go +++ b/internal/api/anonymous_test.go @@ -80,7 +80,7 @@ func (ts *AnonymousTestSuite) TestAnonymousLogins() { func (ts *AnonymousTestSuite) TestConvertAnonymousUserToPermanent() { ts.Config.External.AnonymousUsers.Enabled = true - ts.Config.Sms.TestOTP = map[string]string{"1234567890": "000000"} + ts.Config.Sms.TestOTP = map[string]string{"1234567890": "000000", "1234560000": "000000"} // test OTPs still require setting up an sms provider ts.Config.Sms.Provider = "twilio" ts.Config.Sms.Twilio.AccountSid = "fake-sid" @@ -106,6 +106,22 @@ func (ts *AnonymousTestSuite) TestConvertAnonymousUserToPermanent() { }, verificationType: "phone_change", }, + { + desc: "convert anonymous user to permanent user with email & password", + body: map[string]interface{}{ + "email": "test2@example.com", + "password": "test-password", + }, + verificationType: "email_change", + }, + { + desc: "convert anonymous user to permanent user with phone & password", + body: map[string]interface{}{ + "phone": "1234560000", + "password": "test-password", + }, + verificationType: "phone_change", + }, } for _, c := range cases { @@ -142,6 +158,11 @@ func (ts *AnonymousTestSuite) TestConvertAnonymousUserToPermanent() { require.NotEmpty(ts.T(), user) require.True(ts.T(), user.IsAnonymous) + // Check if user has a password set + if c.body["password"] != nil { + require.True(ts.T(), user.HasPassword()) + } + switch c.verificationType { case mail.EmailChangeVerification: require.NoError(ts.T(), json.NewEncoder(&buffer).Encode(map[string]interface{}{ @@ -150,7 +171,7 @@ func (ts *AnonymousTestSuite) TestConvertAnonymousUserToPermanent() { })) case phoneChangeVerification: require.NoError(ts.T(), json.NewEncoder(&buffer).Encode(map[string]interface{}{ - "phone": "1234567890", + "phone": user.PhoneChange, "token": "000000", "type": c.verificationType, })) @@ -176,11 +197,11 @@ func (ts *AnonymousTestSuite) TestConvertAnonymousUserToPermanent() { switch c.verificationType { case mail.EmailChangeVerification: - assert.Equal(ts.T(), "test@example.com", data.User.GetEmail()) + assert.Equal(ts.T(), c.body["email"], data.User.GetEmail()) assert.Equal(ts.T(), models.JSONMap(models.JSONMap{"provider": "email", "providers": []interface{}{"email"}}), data.User.AppMetaData) assert.NotEmpty(ts.T(), data.User.EmailConfirmedAt) case phoneChangeVerification: - assert.Equal(ts.T(), "1234567890", data.User.GetPhone()) + assert.Equal(ts.T(), c.body["phone"], data.User.GetPhone()) assert.Equal(ts.T(), models.JSONMap(models.JSONMap{"provider": "phone", "providers": []interface{}{"phone"}}), data.User.AppMetaData) assert.NotEmpty(ts.T(), data.User.PhoneConfirmedAt) } diff --git a/internal/api/user.go b/internal/api/user.go index f82d2bf1c..c89c5226d 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -102,11 +102,10 @@ func (a *API) UserUpdate(w http.ResponseWriter, r *http.Request) error { } if user.IsAnonymous { - updatingForbiddenFields := false - updatingForbiddenFields = updatingForbiddenFields || (params.Password != nil && *params.Password != "") - if updatingForbiddenFields { - // CHECK - return unprocessableEntityError(ErrorCodeUnknown, "Updating password of an anonymous user is not possible") + if params.Password != nil && *params.Password != "" { + if params.Email == "" && params.Phone == "" { + return unprocessableEntityError(ErrorCodeValidationFailed, "Updating password of an anonymous user without an email or phone is not allowed") + } } }