User Search by Ids Fails with multiple Ids
Problem
client.userSearchByIds and client.userSearchByQuery using ids are incoherent and give different results.
How to recreate
When I am searching for users by id, I have two options. Either the client.userSearchByIds or client.userSearchByQuery using ids. Therefore I would prefer the first one, but when I give it a list of ids, an error gets returned. When I use the same setup but with client.userSearchByQuery using ids, I get a good result.
console.log(await client.searchUsersByQuery(
{
search:
{
ids: users.map((user) => user.id),
},
}));
>> HTTP CODE: 200
console.log(await client.searchUsersByIds(users.map((user) => user.id)));
>> HTTP CODE: 400
{"statusCode":400,"exception":{"fieldErrors":{"ids":[{"code":"[couldNotConvert]ids","message":"Invalid"}]},"generalErrors":[{"code":"[invalid]","message":"You must specify either the [ids], [queryString], or [query] property."}]}}
This only happens for more than 1 id, otherwise I get the same results.
Setting
I am still running on the v1.22.2, should this bug already be solved, please close this issue, but I could not find it in the Release Notes and this Issues here on github.
Can you share the URL requested by both of these client library calls, please? (Via devtools or some other manner.)
Sure:
HTTP 32: createConnection fusionauth:9011: {
protocol: 'http:',
slashes: true,
auth: null,
host: 'fusionauth',
port: '9011',
hostname: 'fusionauth',
hash: null,
search: '?ids=a585a1ec-f686-4187-84bf-827d3f7b254c%2C1c2e6953-bc48-465b-ba5a-65f9de1db81f%2Cce870517-ce71-46f3-b0f6-343acb17b91a',
query: 'ids=a585a1ec-f686-4187-84bf-827d3f7b254c%2C1c2e6953-bc48-465b-ba5a-65f9de1db81f%2Cce870517-ce71-46f3-b0f6-343acb17b91a',
pathname: '/api/user/search',
path: null,
href: 'http://fusionauth:9011/api/user/search?ids=a585a1ec-f686-4187-84bf-827d3f7b254c%2C1c2e6953-bc48-465b-ba5a-65f9de1db81f%2Cce870517-ce71-46f3-b0f6-343acb17b91a',
method: 'GET',
headers: [Object: null prototype] {
Authorization: [
'QrBB3F7oCEQ8KAythaPG6rSDKC96fGp7EeND5d6cTdJ7H9sHs3kaEozDMEfdsjA3KLjQC456NH63QbR'
],
Accept: [ '*/*' ],
'User-Agent': [ 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)' ],
'Accept-Encoding': [ 'gzip,deflate' ],
Connection: [ 'close' ]
},
agent: undefined,
servername: 'fusionauth',
_agentKey: 'fusionauth:9011:'
}
HTTP 32: sockets fusionauth:9011: 1 1
HTTP 32: outgoing message end.
HTTP 32: call onSocket 1 0
HTTP 32: createConnection fusionauth:9011: {
protocol: 'http:',
slashes: true,
auth: null,
host: 'fusionauth',
port: '9011',
hostname: 'fusionauth',
hash: null,
search: null,
query: null,
pathname: '/api/user/search',
path: null,
href: 'http://fusionauth:9011/api/user/search',
method: 'POST',
headers: [Object: null prototype] {
Authorization: [
'QrBB3F7oCEQ8KAythaPG6rSDKC96fGp7EeND5d6cTdJ7H9sHs3kaEozDMEfdsjA3KLjQC456NH63QbR'
],
'Content-Type': [ 'application/json' ],
Accept: [ '*/*' ],
'Content-Length': [ '137' ],
'User-Agent': [ 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)' ],
'Accept-Encoding': [ 'gzip,deflate' ],
Connection: [ 'close' ]
},
agent: undefined,
servername: 'fusionauth',
_agentKey: 'fusionauth:9011:'
}
I am using the debug flag for the underlying http service of node.
The first request us the one uses searchUserByIds and is performed as a GET request which the second one uses searchUserByQuery and uses a POST request. I did not append the POST body as this is working, but you can see the url of the failing GET request by searchUserByIds.
Thanks! It looks like the get with multiple ids is not being handled correctly.
From the doc: https://fusionauth.io/docs/v1/tech/apis/users/#search-for-users
GET /api/user/search?ids={uuid}&ids={uuid}
From your request:
ids=a585a1ec-f686-4187-84bf-827d3f7b254c%2C1c2e6953-bc48-465b-ba5a-65f9de1db81f%2Cce870517-ce71-46f3-b0f6-343acb17b91a'
which, url decoded, is:
ids=a585a1ec-f686-4187-84bf-827d3f7b254c,1c2e6953-bc48-465b-ba5a-65f9de1db81f,ce870517-ce71-46f3-b0f6-343acb17b91a'
Here's the defn of that API in our DSL: https://github.com/FusionAuth/fusionauth-client-builder/blob/master/src/main/api/searchUsersByIds.json
Here's the resulting TS: https://github.com/FusionAuth/fusionauth-typescript-client/blob/master/src/FusionAuthClient.ts
Here's where we build that TS: https://github.com/FusionAuth/fusionauth-client-builder/blob/master/src/main/client/typescript.client.ftl#L103
Looks like we aren't building the typescript to decompose the array of ids and add multiple ids parameter. Seems like a bug to me.
I am currently using the alternative solution with the POST request as a work around. So no hurries, but happy to help ;)
@mooreds ?ids={uuid}&ids={uuid} that s not make sense !! duplicate arguments
Thanks for the feedback @kamalkech !
I get that it might feel counter-intuitive, but it's actually an approached used by checkboxes all the time. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#handling_multiple_checkboxes for more.
@mooreds ok, just last question, how can fech users by applicationID, can u share any example using database engine search ?
@kamalkech That is a great question for our forum: https://fusionauth.io/community/forum/
An alternative would be to read the documentation on the user search API. The client libraries are a thin wrapper over the APIs, so they should translate directly: https://fusionauth.io/docs/v1/tech/apis/users#search-for-users
Any advanced related to this issue? Did not catch it in the release log bug fixes.
Any advancements related to this issue?
Not yet, unfortunately. Looks like it might affect the ruby, php, and python client libraries as well.
It also might affect these API calls because they all take collections of UUIDs:
- deactivateUsersByIds
- searchUsersByIds
- searchEntitiesByIds
- searchUsers
- deactivateUsers
Not sure when we are going to get to take a look at this, though.
@miaucl hmmm.
I did a test using the latest version of the fusionauth typescript client and things worked as expected.
Here's my index.js
console.log("hello");
import {FusionAuthClient} from '@fusionauth/typescript-client';
const client = new FusionAuthClient('90d8fb62-6f13-47d4-8ef6-1c3e687883c6', 'https://sandbox.fusionauth.io');
client.searchUsersByIds(['00000000-0000-0000-0000-000000000005','00000000-0000-0000-0000-000000000004'])
.then(clientResponse => {
console.log("User:", JSON.stringify(clientResponse.response, null, 2));
}).catch(console.error);
Here's my package.json:
{
"name": "runit",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"type": "module",
"license": "ISC",
"dependencies": {
"@fusionauth/typescript-client": "^1.53.0"
}
}
Here's how I run it: node index.js with node version 21.7.1.
It gives back two users and I don't see any issue with it.
I also looked at the ruby version and it seems fine.
Maybe I misunderstand the issue, but it appears that searchUsersByIds works just fine.
If you can provide an example JS script against the latest version of FusionAuth showing the issue, I'd be happy to take a closer look.
Cannot reproduce it anymore indeed, this got fixed I guess :)