fusionauth-typescript-client icon indicating copy to clipboard operation
fusionauth-typescript-client copied to clipboard

Register returns with HTTP 400

Open nscarlson opened this issue 5 years ago • 14 comments

FusionAuth version: 1.13.2

The following code does not work currently. FusionAuth throws a 400, without any description of why it fails.

const client = new FusionAuthClient(
    <api_key>,
    <base_url>,
)

const registerAccountResponse = await client.register(uuid, {
    registration: {
        applicationId: APPLICATION_ID,
    },
        user: {
            email,
            password,
        },
    }
)

Manually crafting the request via Insomnia works, like so:

POST https://<base_url>/api/user/registration

Body

{
	"registration": {
		"applicationId": "<application_id>"
	},

	"user": {
		"email": "[email protected]",
		"password": "********"
	}
}

Headers Content-Type: application/json Authorization: <api_key>

I'm assuming that the client is not correctly passing the Authorization header it was instantiated with.

EDIT: After a debugging session, I've confirmed that the Authorization header is indeed correctly being set for the API call to FusionAuth.

Tried setting up a request via Axios like so, and also receive a 400 bad response:

    const registerAccountResponse = await axios.post(
        `${baseURL}/api/user/registration`,
        {
            registration: {
                applicationId: APPLICATION_ID,
            },
            user: {
                email,
                password,
            },
        },
        {
            headers: {
                'Content-Type': 'application/json',
                Authorization: API_KEY,
            },
        },
    )

nscarlson avatar Jan 17 '20 23:01 nscarlson

Assuming it is related to this issue where the error JSON body is not coming back correctly. https://github.com/FusionAuth/fusionauth-typescript-client/issues/9

When you use a different REST client, what is returned in the body when you see a 400?

robotdan avatar Jan 18 '20 01:01 robotdan

When you use a different REST client, what is returned in the body when you see a 400?

This is the body I get back in the case of attempting to register a duplicate email:

{
  "fieldErrors": {
    "user.email": [
      {
        "code": "[duplicate]user.email",
        "message": "A User with email = [[email protected]] already exists."
      }
    ]
  }
}

nscarlson avatar Jan 18 '20 01:01 nscarlson

Ah, ok, so you know what the error is - and the issue is only that the JSON response is not coming back correctly.

Can you try 1.13.2 and see if you can still recreate? https://www.npmjs.com/package/@fusionauth/typescript-client

robotdan avatar Jan 18 '20 01:01 robotdan

Can you try 1.13.2 and see if you can still recreate? https://www.npmjs.com/package/@fusionauth/typescript-client

Now this shines more light on the real issue. When calling the client with an empty string for UUID, like so:

fusionAuthClient.register('', {
            registration: {
                applicationId: APPLICATION_ID,
            },
            user: {
                email,
                password,
            },
        })

I'm getting this error:

ClientResponse {
  statusCode: 400,
  response: { fieldErrors: { userId: [Array] } }
}

It's not an issue if I generate and pass in my own valid UUID. Documentation indicates that this argument is optional, however.

nscarlson avatar Jan 18 '20 02:01 nscarlson

Does passing in a null instead of an empty setting make any difference?

robotdan avatar Jan 18 '20 02:01 robotdan

Does passing in a null instead of an empty setting make any difference?

null, undefined, etc all cause type errors, from the FusionAuthClient.d.ts definition file:

declare type UUID = string;

and

register(userId: UUID, request: RegistrationRequest): Promise<ClientResponse<RegistrationResponse>>;

nscarlson avatar Jan 18 '20 02:01 nscarlson

Ok, thanks. That is a bug in the client, we'll fix that in an upcoming release. Actually the empty string should work as well, we'll look into this further.

robotdan avatar Jan 18 '20 02:01 robotdan

@tyduptyler13 can we make the userId: UUID parameter nullable (not optional) by either changing the UUID type def or maybe change the syntax in the request parameter to allow for null or undefined in addition to empty string?

For example change this

type UUID = string;

to

type UUID = string | null | undefined;

but would this change the usage in an interface type such as this? In other words, here we are indicating the id and tenantId fields are nullable, does this change if we add null | undefined to the UUID type def?

export interface BaseEvent {
  createInstant?: number;
  id?: UUID;
  tenantId?: UUID;
}

robotdan avatar Jan 18 '20 02:01 robotdan

We just need to make it so that any instance where a parameter is a UUID, we add the ? to it so that null/undefined is legal.

Ex:

register(id?: UUID...)

tyduptyler13 avatar Jan 21 '20 23:01 tyduptyler13

I thought adding ? made the parameter optional, which means it has to be after required parameters.

However, currently most of the methods we'd want to change are in the form of

foo(id: UUID, request: RequestObject)

robotdan avatar Jan 22 '20 04:01 robotdan

@robotdan You are correct. Null is always implicitly allowed. The ? makes it optional and thus it cannot come first in the argument list. I also just checked and we have tests that call functions with null passed in for UUID parameters. I suspect this issue has to do with his version of typescript or maybe his IDE?

tyduptyler13 avatar Apr 21 '20 18:04 tyduptyler13

What's the status of this? The user ID still seems to required and disallows you to create and register the user with this one register function. The same The Id of the User was not specified on the URL. error seems to be result even with a regular HTTP request without this TypeScript client. The documentation is also a bit misleading since it states that the user ID is optional.. Hoping for a quick fix!

For now I'm able to go around this by first creating the user with createUser and then doing the registration afterwards, however this isn't the most ideal solution.

laznic avatar Aug 23 '20 17:08 laznic

Facing same issue with FusionAuth Typescript client 1.41.0 . The register method successfully registers a new user but the client response promise resolves to an error with empty error body {} when the userId in the request is undefined.

kupilikula avatar Nov 25 '22 18:11 kupilikula

Nevermind, the error I was getting was from processing the response JSON wrongly. It works for me now.

kupilikula avatar Nov 25 '22 19:11 kupilikula