Skip to content

Commit

Permalink
Merge pull request #427 from supertokens/fix/any-type-of-value
Browse files Browse the repository at this point in the history
fix: Add support for any type in value field instead of only string
  • Loading branch information
rishabhpoddar authored Sep 24, 2024
2 parents b314858 + f863cbe commit 84851f5
Show file tree
Hide file tree
Showing 9 changed files with 485 additions and 24 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [unreleased]

## [0.24.3] - 2024-09-24

- Adds support for form field related improvements by making fields accept any type of values
- Adds support for optional fields to properly optional

## [0.24.2] - 2024-09-03

- Fixes memory leak with the JWKS cache.
Expand Down
64 changes: 54 additions & 10 deletions recipe/emailpassword/api/implementation.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,17 @@ func MakeAPIImplementation() epmodels.APIInterface {
var email string
for _, formField := range formFields {
if formField.ID == "email" {
email = formField.Value
// NOTE: This check will never actually fail because the parent
// function already checks for the type however in order to read the
// value as a string, it's safer to keep it here in case something changes
// in the future.
valueAsString, parseErr := withValueAsString(formField.Value, "email value needs to be a string")
if parseErr != nil {
return epmodels.GeneratePasswordResetTokenPOSTResponse{
GeneralError: &supertokens.GeneralErrorResponse{Message: parseErr.Error()},
}, nil
}
email = valueAsString
}
}

Expand Down Expand Up @@ -102,7 +112,17 @@ func MakeAPIImplementation() epmodels.APIInterface {
var newPassword string
for _, formField := range formFields {
if formField.ID == "password" {
newPassword = formField.Value
// NOTE: This check will never actually fail because the parent
// function already checks for the type however in order to read the
// value as a string, it's safer to keep it here in case something changes
// in the future.
valueAsString, parseErr := withValueAsString(formField.Value, "password value needs to be a string")
if parseErr != nil {
return epmodels.ResetPasswordPOSTResponse{
GeneralError: &supertokens.GeneralErrorResponse{Message: parseErr.Error()},
}, nil
}
newPassword = valueAsString
}
}

Expand All @@ -126,10 +146,22 @@ func MakeAPIImplementation() epmodels.APIInterface {
var email string
var password string
for _, formField := range formFields {
if formField.ID == "email" {
email = formField.Value
} else if formField.ID == "password" {
password = formField.Value
// NOTE: The check for type of password/email will never actually
// fail because the parent function already checks for the type
// however in order to read the value as a string, it's safer to
// keep it here in case something changes in the future.
if formField.ID == "email" || formField.ID == "password" {
valueAsString, parseErr := withValueAsString(formField.Value, fmt.Sprintf("%s value needs to be a string", formField.ID))
if parseErr != nil {
return epmodels.SignInPOSTResponse{
WrongCredentialsError: &struct{}{},
}, nil
}
if formField.ID == "email" {
email = valueAsString
} else {
password = valueAsString
}
}
}

Expand Down Expand Up @@ -164,10 +196,22 @@ func MakeAPIImplementation() epmodels.APIInterface {
var email string
var password string
for _, formField := range formFields {
if formField.ID == "email" {
email = formField.Value
} else if formField.ID == "password" {
password = formField.Value
// NOTE: The check for type of password/email will never actually
// fail because the parent function already checks for the type
// however in order to read the value as a string, it's safer to
// keep it here in case something changes in the future.
if formField.ID == "email" || formField.ID == "password" {
valueAsString, parseErr := withValueAsString(formField.Value, fmt.Sprintf("%s value needs to be a string", formField.ID))
if parseErr != nil {
return epmodels.SignUpPOSTResponse{
GeneralError: &supertokens.GeneralErrorResponse{Message: parseErr.Error()},
}, nil
}
if formField.ID == "email" {
email = valueAsString
} else {
password = valueAsString
}
}
}

Expand Down
40 changes: 29 additions & 11 deletions recipe/emailpassword/api/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ import (
"github.com/supertokens/supertokens-golang/supertokens"
)

func withValueAsString(emailValue interface{}, errorStr string) (string, error) {
// Throw error if the value is not a string
valueAsString, asStrOk := emailValue.(string)
if !asStrOk {
return "", fmt.Errorf(errorStr)
}

return valueAsString, nil
}

func validateFormFieldsOrThrowError(configFormFields []epmodels.NormalisedFormField, formFieldsRaw interface{}, tenantId string) ([]epmodels.TypeFormField, error) {
if formFieldsRaw == nil {
return nil, supertokens.BadInputError{
Expand Down Expand Up @@ -56,14 +66,6 @@ func validateFormFieldsOrThrowError(configFormFields []epmodels.NormalisedFormFi
}
}

if rawFormField.(map[string]interface{})["value"] != nil {
if _, ok := rawFormField.(map[string]interface{})["value"].(string); !ok {
return nil, supertokens.BadInputError{
Msg: "formFields must be an array of objects containing id and value of type string",
}
}
}

jsonformField, err := json.Marshal(rawFormField)
if err != nil {
return nil, err
Expand All @@ -74,10 +76,17 @@ func validateFormFieldsOrThrowError(configFormFields []epmodels.NormalisedFormFi
return nil, err
}

if formField.ID == "email" {
if formField.ID == "email" || formField.ID == "password" {
valueAsString, parseErr := withValueAsString(formField.Value, fmt.Sprintf("%s value must be a string", formField.ID))
if parseErr != nil {
return nil, supertokens.BadInputError{
Msg: parseErr.Error(),
}
}

formFields = append(formFields, epmodels.TypeFormField{
ID: formField.ID,
Value: strings.TrimSpace(formField.Value),
Value: strings.TrimSpace(valueAsString),
})
} else {
formFields = append(formFields, epmodels.TypeFormField{
Expand Down Expand Up @@ -106,7 +115,16 @@ func validateFormOrThrowError(configFormFields []epmodels.NormalisedFormField, i
}
}

isValidInput := input.Value != ""
isValidInput := true
if input.Value == nil {
isValidInput = false
} else {
// If it is a string, it shouldn't be empty.
valueAsStr, err := withValueAsString(input.Value, "")
if err == nil && strings.TrimSpace(valueAsStr) == "" {
isValidInput = false
}
}

// If the field is not option and input is invalid, we should
// throw a validation error.
Expand Down
Loading

0 comments on commit 84851f5

Please sign in to comment.