Hey all, I am trying to override an API response o...
# general
a
Hey all, I am trying to override an API response of CreateCodePOST - I want to override response of both success and error scenarios, is there any reference doc for the same? thanks
r
hey @alisha
are you using golang on the backend?
a
yes
r
ok. give me a min
Copy code
go
func main() {

    passwordless.Init(plessmodels.TypeInput{
        Override: &plessmodels.OverrideStruct{
            APIs: func(originalImplementation plessmodels.APIInterface) plessmodels.APIInterface {
                originalCreateCodePOST := *originalImplementation.CreateCodePOST
                (*originalImplementation.CreateCodePOST) = func(email, phoneNumber *string, options plessmodels.APIOptions, userContext supertokens.UserContext) (plessmodels.CreateCodePOSTResponse, error) {
                    resp, err := originalCreateCodePOST(email, phoneNumber, options, userContext)
                    if err != nil {
                        // this is usually some 500 error like core connection issues..
                        return plessmodels.CreateCodePOSTResponse{}, err
                    }

                    if resp.GeneralError != nil {
                        // this is usually some custom error message which will be displayed
                        // on the frontend
                        return resp, err
                    }

                    // code creation was successful
                    return resp, err
                }
                return originalImplementation
            },
        },
    })
}
so in the different
if
conditions, you can do whatever you like. You can even send a response to the client directly (using
options.Res
).
a
super, thanks will try this out
I am using thridpartypasswordless recipe, the init function takes the 1st param config of type tplmodels.TypeInput
the above example is of type plessmodels.TypeInput
r
right yea.. so you will need to do according to that. But overall it's very similar
a
I have this case where I want to capture invalid phone error and modify the error message and http status code
Copy code
{
  "message": "Phone number is invalid",
  "status": "GENERAL_ERROR"
}
I am not able to capture this message and status in the resp var
r
Ah right! Then you should provide the
ValidatePhoneNumber
function in the init call yourself: https://pkg.go.dev/github.com/supertokens/supertokens-golang@v0.6.0/recipe/passwordless/plessmodels#ContactMethodPhoneConfig
and validate the phone number and in case its invalid, you can return your own message
for validation of the phone number, you can copy the code from the SDK
a
oh okay
a
and I also want to handle bad request scenarios { "message": "Please provide exactly one of email or phoneNumber" }
in this case I want to change the message too
r
Well.. to do that, you can add your own middleware which runs before our middleware, checks for the input if the path and method is = to the create code API and in case the input is bad, then you can send your own response
unfortunately, that's the easiest way to do this.
may i ask the use case for this?
a
got it, thanks
r
cause this message is returned only in case there is a coding error from the frontend - the end user should never see this anyway
a
just exploring ways on how to go about using this
yes this will not go to the user anyway
r
ah right.. normally overriding a bad request error is not needed. But well,., it's possible regardles.
a
thanks a lot, this helped πŸ™‚
hi again
r
hey!
a
I tried implementing a custom phone validate function which returns a different error message, but is there a way to return a 400 response when there is a bad phone, instead of 200?
r
hmm. For that, you will have to probably disable the default API and make your own using our functions from the SDK
a
oh ok, is there any reference for the same?
Actually, there is an easier way. In the custom validate function, you just return nil all the time (thereby saying that any phone number is valid). That phone number will be then sent to the API call in which you can override it to check the format yourself. In case it's invalid, then you can send a custom response with whatever status code you want: https://supertokens.com/docs/thirdpartyemailpassword/advanced-customizations/apis-override/custom-response/api-override
a
oh will try that, thanks
hi again
I have implemented the above solution, but I am getting the following error
Headers were already written. Wanted to override status code 400 with 500
Copy code
(*originalImplementation.CreateCodePOST) = func(email *string, phoneNumber *string, optionsCreateCode plessmodels.APIOptions, userContextCreateCode supertokens.UserContext) (plessmodels.CreateCodePOSTResponse, error) {
                            err := validatePhone(*phoneNumber)
                            if err != nil {
                                responseJson := map[string]interface{}{
                                    "message": err,
                                }

                                bytes, _ := json.Marshal(responseJson)

                                optionsCreateCode.Res.Header().Set("Content-Type", "application/json")
                                optionsCreateCode.Res.WriteHeader(400)
                                optionsCreateCode.Res.Write(bytes)

                                return plessmodels.CreateCodePOSTResponse{}, nil
                            }
                            return originalCreateCodePOST(email, phoneNumber, optionsCreateCode, userContextCreateCode)
                        }
not sure what I am doing wrong
r
Can you update to the latest version and try again? There was a bug related to this which we solved yesterday.
a
upgraded to v0.6.2, still facing the same error
r
ok checking. @sattvikc can help with this
s
@alisha I am verifying this, will get back
from quick look, seems like you are modifying the original implementation and entering recursion. instead can you try this code:
Copy code
originalCreateCodePOST = *originalImplementation.CreateCodePOST
newCreateCodePOST = func(email *string, phoneNumber *string, optionsCreateCode plessmodels.APIOptions, userContextCreateCode supertokens.UserContext) (plessmodels.CreateCodePOSTResponse, error) {
    err := validatePhone(*phoneNumber)
    if err != nil {
        responseJson := map[string]interface{}{
            "message": err,
        }

        bytes, _ := json.Marshal(responseJson)

        optionsCreateCode.Res.Header().Set("Content-Type", "application/json")
        optionsCreateCode.Res.WriteHeader(400)
        optionsCreateCode.Res.Write(bytes)

        return plessmodels.CreateCodePOSTResponse{}, nil
    }
    return originalCreateCodePOST(email, phoneNumber, optionsCreateCode, userContextCreateCode)
}
originalImplementation.CreateCodePOST = &newCreateCodePOST
r
@sattvikc it's not a problem of infinite recursion
Cause
originalCreateCodePOST
won't be called at all anyway
s
I'll implement locally and suggest the fix
r
since a custom response is being sent
So it's some other issue
a
thanks @sattvikc
s
@alisha please try this:
Copy code
(*originalImplementation.CreateCodePOST) = func(email *string, phoneNumber *string, optionsCreateCode plessmodels.APIOptions, userContextCreateCode supertokens.UserContext) (plessmodels.CreateCodePOSTResponse, error) {
                    err := validatePhone(*phoneNumber)
                    if err != nil {
                        responseJson := map[string]interface{}{
                            "message": err.Error(),
                        }

                        bytes, _ := json.Marshal(responseJson)

                        optionsCreateCode.Res.Header().Set("Content-Type", "application/json")
                        optionsCreateCode.Res.WriteHeader(400)
                        optionsCreateCode.Res.Write(bytes)

                        return plessmodels.CreateCodePOSTResponse{
                            OK: &struct {
                                DeviceID         string
                                PreAuthSessionID string
                                FlowType         string
                            }{},
                        }, nil
                    }
                    return originalCreateCodePOST(email, phoneNumber, optionsCreateCode, userContextCreateCode)
                }
                return originalImplementation
a
not sure what is going wrong, but it looks like I am not able to override the CreateCodePOST function
r
Can you share more of the code?
The whole Override input object perhaps
a
supertokens.Init
r
So it seems about right. But the
fmt.Println("inside override")
is not actually inside the override. To put it in the override, you would have to put it before
err := validatePhone(*phoneNumber)
line
can you move the log right above
err := validatePhone(*phoneNumber)
and see if it gets printed out when you call the API?
a
its not logging trued before err := validatePhone(*phoneNumber)
r
what is the output?
a
its printing if its not a bad number
if I pass an invalid number I dont see the log printing
r
what do you see in that case? what is the API's output?
a
Copy code
{
  "message": "Phone number is invalid",
  "status": "GENERAL_ERROR"
}
with a 200
r
ah right yea.. cause it's using our default validator which is rejecting the request before your override function is called
a
oh yes, I missed thus
r
What have you given in
ContactMethodPhone
?
a
trying with a custom validator
r
you should give something like:
Copy code
go
ContactMethodPhone: plessmodels.ContactMethodPhoneConfig{
            ValidatePhoneNumber: func(phoneNumber interface{}) *string {
                return nil
            },
        },
this will basically allow any phone number to pass through
and should call your override function
a
working now, I missed adding a custom validate phone number function which returns nil
r
cool!
a
thanks a lot!
hey again
this time I am overriding ThirdPartySignInUpPOST to return a custom response
I am getting the following
Copy code
Headers were already written. Wanted to override status code 200 with 500
r
@sattvikc can you see this please?
s
@rp sure
@alisha could you share your code snippet?
r
It’s shared already
See the message.txt file
s
I'll verify and get back
hi @alisha
a
hey
s
can you update ur return statement to this:
a
worked
thanks a ton!
s
pleasure πŸ™‚
generally on any override, ensure no nil is passed with the OK response
a
will take care, thanks
r
hey @alisha thanks for pointing this error out. You can use our latest version (0.6.4) which contains this bug fix.
a
ok, thanks @rp
3 Views