Skip to content

Commit 0e897c7

Browse files
committed
optional password validation in updateEmailOrPassword
1 parent 0d74211 commit 0e897c7

File tree

12 files changed

+49
-33
lines changed

12 files changed

+49
-33
lines changed

recipe/dashboard/api/userdetails/userPut.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func updateEmailForRecipeId(recipeId string, userId string, email string) (updat
7474
}, nil
7575
}
7676

77-
updateResponse, err := emailpassword.UpdateEmailOrPassword(userId, &email, nil)
77+
updateResponse, err := emailpassword.UpdateEmailOrPassword(userId, &email, nil, nil)
7878

7979
if err != nil {
8080
return updateEmailResponse{}, err
@@ -113,7 +113,7 @@ func updateEmailForRecipeId(recipeId string, userId string, email string) (updat
113113
}, nil
114114
}
115115

116-
updateResponse, err := thirdpartyemailpassword.UpdateEmailOrPassword(userId, &email, nil)
116+
updateResponse, err := thirdpartyemailpassword.UpdateEmailOrPassword(userId, &email, nil, nil)
117117

118118
if err != nil {
119119
return updateEmailResponse{}, err

recipe/emailpassword/authFlow_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import (
3535
"github.com/supertokens/supertokens-golang/test/unittesting"
3636
)
3737

38-
//SigninFeature Tests
38+
// SigninFeature Tests
3939
func TestDisablingAPIDefaultSigninDoesNotWork(t *testing.T) {
4040
configValue := supertokens.TypeInput{
4141
Supertokens: &supertokens.ConnectionInfo{
@@ -1234,7 +1234,7 @@ func TestHandlePostSignInFunction(t *testing.T) {
12341234

12351235
}
12361236

1237-
//Signout Feature tests
1237+
// Signout Feature tests
12381238
func TestDefaultSignoutRouteRevokesSession(t *testing.T) {
12391239
customAntiCsrfVal := "VIA_TOKEN"
12401240
configValue := supertokens.TypeInput{
@@ -1474,7 +1474,7 @@ func TestSignoutAPIreturnsTryRefreshTokenAndSignoutShouldReturnOK(t *testing.T)
14741474
assert.Equal(t, "", cookieData2["refreshTokenDomain"])
14751475
}
14761476

1477-
//Signup Feature tests
1477+
// Signup Feature tests
14781478
func TestDisablingAPIDefaultSignUpDoesNotWork(t *testing.T) {
14791479
configValue := supertokens.TypeInput{
14801480
Supertokens: &supertokens.ConnectionInfo{

recipe/emailpassword/epmodels/recipeInterface.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ type RecipeInterface struct {
2424
GetUserByEmail *func(email string, userContext supertokens.UserContext) (*User, error)
2525
CreateResetPasswordToken *func(userID string, userContext supertokens.UserContext) (CreateResetPasswordTokenResponse, error)
2626
ResetPasswordUsingToken *func(token string, newPassword string, userContext supertokens.UserContext) (ResetPasswordUsingTokenResponse, error)
27-
UpdateEmailOrPassword *func(userId string, email *string, password *string, userContext supertokens.UserContext) (UpdateEmailOrPasswordResponse, error)
27+
UpdateEmailOrPassword *func(userId string, email *string, password *string, applyPasswordPolicy *bool, userContext supertokens.UserContext) (UpdateEmailOrPasswordResponse, error)
2828
}
2929

3030
type SignUpResponse struct {
@@ -56,7 +56,8 @@ type ResetPasswordUsingTokenResponse struct {
5656
}
5757

5858
type UpdateEmailOrPasswordResponse struct {
59-
OK *struct{}
60-
UnknownUserIdError *struct{}
61-
EmailAlreadyExistsError *struct{}
59+
OK *struct{}
60+
UnknownUserIdError *struct{}
61+
EmailAlreadyExistsError *struct{}
62+
PasswordPolicyViolatedError *struct{}
6263
}

recipe/emailpassword/main.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@ func ResetPasswordUsingTokenWithContext(token string, newPassword string, userCo
7474
return (*instance.RecipeImpl.ResetPasswordUsingToken)(token, newPassword, userContext)
7575
}
7676

77-
func UpdateEmailOrPasswordWithContext(userId string, email *string, password *string, userContext supertokens.UserContext) (epmodels.UpdateEmailOrPasswordResponse, error) {
77+
func UpdateEmailOrPasswordWithContext(userId string, email *string, password *string, applyPasswordPolicy *bool, userContext supertokens.UserContext) (epmodels.UpdateEmailOrPasswordResponse, error) {
7878
instance, err := GetRecipeInstanceOrThrowError()
7979
if err != nil {
8080
return epmodels.UpdateEmailOrPasswordResponse{}, nil
8181
}
82-
return (*instance.RecipeImpl.UpdateEmailOrPassword)(userId, email, password, userContext)
82+
return (*instance.RecipeImpl.UpdateEmailOrPassword)(userId, email, password, applyPasswordPolicy, userContext)
8383
}
8484

8585
func SendEmailWithContext(input emaildelivery.EmailType, userContext supertokens.UserContext) error {
@@ -114,8 +114,8 @@ func ResetPasswordUsingToken(token string, newPassword string) (epmodels.ResetPa
114114
return ResetPasswordUsingTokenWithContext(token, newPassword, &map[string]interface{}{})
115115
}
116116

117-
func UpdateEmailOrPassword(userId string, email *string, password *string) (epmodels.UpdateEmailOrPasswordResponse, error) {
118-
return UpdateEmailOrPasswordWithContext(userId, email, password, &map[string]interface{}{})
117+
func UpdateEmailOrPassword(userId string, email *string, password *string, applyPasswordPolicy *bool) (epmodels.UpdateEmailOrPasswordResponse, error) {
118+
return UpdateEmailOrPasswordWithContext(userId, email, password, applyPasswordPolicy, &map[string]interface{}{})
119119
}
120120

121121
func SendEmail(input emaildelivery.EmailType) error {

recipe/emailpassword/recipe.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ func MakeRecipe(recipeId string, appInfo supertokens.NormalisedAppinfo, config *
5353
verifiedConfig := validateAndNormaliseUserInput(r, appInfo, config)
5454
r.Config = verifiedConfig
5555
r.APIImpl = verifiedConfig.Override.APIs(api.MakeAPIImplementation())
56-
r.RecipeImpl = verifiedConfig.Override.Functions(MakeRecipeImplementation(*querierInstance))
56+
var getEmailPasswordConfig = func() epmodels.TypeNormalisedInput {
57+
return verifiedConfig
58+
}
59+
r.RecipeImpl = verifiedConfig.Override.Functions(MakeRecipeImplementation(*querierInstance, getEmailPasswordConfig))
5760

5861
if emailDeliveryIngredient != nil {
5962
r.EmailDelivery = *emailDeliveryIngredient

recipe/emailpassword/recipeImplementation.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616
package emailpassword
1717

1818
import (
19+
"errors"
1920
"github.com/supertokens/supertokens-golang/recipe/emailpassword/epmodels"
2021
"github.com/supertokens/supertokens-golang/supertokens"
2122
)
2223

23-
func MakeRecipeImplementation(querier supertokens.Querier) epmodels.RecipeInterface {
24+
func MakeRecipeImplementation(querier supertokens.Querier, getEmailPasswordConfig func() epmodels.TypeNormalisedInput) epmodels.RecipeInterface {
2425
signUp := func(email, password string, userContext supertokens.UserContext) (epmodels.SignUpResponse, error) {
2526
response, err := querier.SendPostRequest("/recipe/signup", map[string]interface{}{
2627
"email": email,
@@ -158,14 +159,25 @@ func MakeRecipeImplementation(querier supertokens.Querier) epmodels.RecipeInterf
158159
}
159160
}
160161

161-
updateEmailOrPassword := func(userId string, email, password *string, userContext supertokens.UserContext) (epmodels.UpdateEmailOrPasswordResponse, error) {
162+
updateEmailOrPassword := func(userId string, email, password *string, applyPasswordPolicy *bool, userContext supertokens.UserContext) (epmodels.UpdateEmailOrPasswordResponse, error) {
162163
requestBody := map[string]interface{}{
163164
"userId": userId,
164165
}
165166
if email != nil {
166167
requestBody["email"] = email
167168
}
168169
if password != nil {
170+
if applyPasswordPolicy == nil || *applyPasswordPolicy {
171+
formFields := getEmailPasswordConfig().SignUpFeature.FormFields
172+
for i := range formFields {
173+
if formFields[i].ID == "password" {
174+
err := formFields[i].Validate(password)
175+
if err == nil {
176+
return epmodels.UpdateEmailOrPasswordResponse{PasswordPolicyViolatedError: &struct{}{}}, errors.New(*err)
177+
}
178+
}
179+
}
180+
}
169181
requestBody["password"] = password
170182
}
171183
response, err := querier.SendPutRequest("/recipe/user", requestBody)

recipe/emailpassword/updateEmailPass_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func TestUpdateEmailPass(t *testing.T) {
100100
email := "[email protected]"
101101
password := "testPass"
102102

103-
UpdateEmailOrPassword(data["user"].(map[string]interface{})["id"].(string), &email, &password)
103+
UpdateEmailOrPassword(data["user"].(map[string]interface{})["id"].(string), &email, &password, nil)
104104

105105
res1, err := unittesting.SignInRequest("[email protected]", "validpass123", testServer.URL)
106106

recipe/thirdpartyemailpassword/main.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,12 @@ func ResetPasswordUsingTokenWithContext(token, newPassword string, userContext s
9191
return (*instance.RecipeImpl.ResetPasswordUsingToken)(token, newPassword, userContext)
9292
}
9393

94-
func UpdateEmailOrPasswordWithContext(userId string, email *string, password *string, userContext supertokens.UserContext) (epmodels.UpdateEmailOrPasswordResponse, error) {
94+
func UpdateEmailOrPasswordWithContext(userId string, email *string, password *string, applyPasswordPOlicy *bool, userContext supertokens.UserContext) (epmodels.UpdateEmailOrPasswordResponse, error) {
9595
instance, err := GetRecipeInstanceOrThrowError()
9696
if err != nil {
9797
return epmodels.UpdateEmailOrPasswordResponse{}, err
9898
}
99-
return (*instance.RecipeImpl.UpdateEmailOrPassword)(userId, email, password, userContext)
99+
return (*instance.RecipeImpl.UpdateEmailOrPassword)(userId, email, password, applyPasswordPOlicy, userContext)
100100
}
101101

102102
func SendEmailWithContext(input emaildelivery.EmailType, userContext supertokens.UserContext) error {
@@ -139,8 +139,8 @@ func ResetPasswordUsingToken(token, newPassword string) (epmodels.ResetPasswordU
139139
return ResetPasswordUsingTokenWithContext(token, newPassword, &map[string]interface{}{})
140140
}
141141

142-
func UpdateEmailOrPassword(userId string, email *string, password *string) (epmodels.UpdateEmailOrPasswordResponse, error) {
143-
return UpdateEmailOrPasswordWithContext(userId, email, password, &map[string]interface{}{})
142+
func UpdateEmailOrPassword(userId string, email *string, password *string, applyPasswordPolicy *bool) (epmodels.UpdateEmailOrPasswordResponse, error) {
143+
return UpdateEmailOrPasswordWithContext(userId, email, password, applyPasswordPolicy, &map[string]interface{}{})
144144
}
145145

146146
func SendEmail(input emaildelivery.EmailType) error {

recipe/thirdpartyemailpassword/recipe.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ func MakeRecipe(recipeId string, appInfo supertokens.NormalisedAppinfo, config *
5454
return Recipe{}, err
5555
}
5656
r.Config = verifiedConfig
57+
var emailPasswordRecipe emailpassword.Recipe
5758
{
5859
emailpasswordquerierInstance, err := supertokens.GetNewQuerierInstanceOrThrowError(emailpassword.RECIPE_ID)
5960
if err != nil {
@@ -63,14 +64,14 @@ func MakeRecipe(recipeId string, appInfo supertokens.NormalisedAppinfo, config *
6364
if err != nil {
6465
return Recipe{}, err
6566
}
66-
67-
r.RecipeImpl = verifiedConfig.Override.Functions(recipeimplementation.MakeRecipeImplementation(*emailpasswordquerierInstance, thirdpartyquerierInstance))
67+
var getEmailPasswordConfig = func() epmodels.TypeNormalisedInput {
68+
return emailPasswordRecipe.Config
69+
}
70+
r.RecipeImpl = verifiedConfig.Override.Functions(recipeimplementation.MakeRecipeImplementation(*emailpasswordquerierInstance, thirdpartyquerierInstance, getEmailPasswordConfig))
6871
}
6972
r.APIImpl = verifiedConfig.Override.APIs(api.MakeAPIImplementation())
7073

71-
var emailPasswordRecipe emailpassword.Recipe
7274
emailPasswordRecipeImpl := recipeimplementation.MakeEmailPasswordRecipeImplementation(r.RecipeImpl)
73-
7475
if emailDeliveryIngredient != nil {
7576
r.EmailDelivery = *emailDeliveryIngredient
7677
} else {

recipe/thirdpartyemailpassword/recipeimplementation/emailPasswordRecipeImplementation.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ func MakeEmailPasswordRecipeImplementation(recipeImplementation tpepmodels.Recip
106106
return (*recipeImplementation.ResetPasswordUsingToken)(token, newPassword, userContext)
107107
}
108108

109-
updateEmailOrPassword := func(userId string, email, password *string, userContext supertokens.UserContext) (epmodels.UpdateEmailOrPasswordResponse, error) {
110-
return (*recipeImplementation.UpdateEmailOrPassword)(userId, email, password, userContext)
109+
updateEmailOrPassword := func(userId string, email, password *string, applyPasswordPolicy *bool, userContext supertokens.UserContext) (epmodels.UpdateEmailOrPasswordResponse, error) {
110+
return (*recipeImplementation.UpdateEmailOrPassword)(userId, email, password, applyPasswordPolicy, userContext)
111111
}
112112

113113
return epmodels.RecipeInterface{

0 commit comments

Comments
 (0)