diff --git a/src/GoTrueAdminApi.ts b/src/GoTrueAdminApi.ts index 8f4ee2ba..a386cd4c 100644 --- a/src/GoTrueAdminApi.ts +++ b/src/GoTrueAdminApi.ts @@ -169,10 +169,11 @@ export default class GoTrueAdminApi { * Get a list of users. * * This function should only be called on a server. Never expose your `service_role` key in the browser. - * @param params An object which supports `page` and `perPage` as numbers, to alter the paginated results. + * @param params An object which supports `page` and `perPage` as numbers, to alter the paginated results, + * and `filter` string to search for users by email address. */ async listUsers( - params?: PageParams + params?: PageParams & { filter?: string } ): Promise< | { data: { users: User[]; aud: string } & Pagination; error: null } | { data: { users: [] }; error: AuthError } @@ -185,6 +186,7 @@ export default class GoTrueAdminApi { query: { page: params?.page?.toString() ?? '', per_page: params?.perPage?.toString() ?? '', + ...(params?.filter ? { filter: params.filter } : {}), }, xform: _noResolveJsonResponse, }) @@ -195,8 +197,13 @@ export default class GoTrueAdminApi { const links = response.headers.get('link')?.split(',') ?? [] if (links.length > 0) { links.forEach((link: string) => { - const page = parseInt(link.split(';')[0].split('=')[1].substring(0, 1)) - const rel = JSON.parse(link.split(';')[1].split('=')[1]) + const [urlPart, relPart] = link.split(';').map(part => part.trim()); + const url = urlPart.slice(1, -1); // Remove the leading "" + + const searchParams = new URLSearchParams(url.split('?')[1]); + const page = parseInt(searchParams.get('page') || '1', 10); + const rel = relPart.split('=')[1].replace(/"/g, ''); + pagination[`${rel}Page`] = page }) diff --git a/test/GoTrueApi.test.ts b/test/GoTrueApi.test.ts index e1afc076..e007a626 100644 --- a/test/GoTrueApi.test.ts +++ b/test/GoTrueApi.test.ts @@ -99,6 +99,28 @@ describe('GoTrueAdminApi', () => { expect(emails.length).toBeGreaterThan(0) expect(emails).toContain(email) }) + + test('listUsers() should support filter property', async () => { + const { email } = mockUserCredentials() + const { error: createError, data: createdUser } = await createNewUserWithEmail({ email }) + expect(createError).toBeNull() + expect(createdUser.user).not.toBeUndefined() + + const { error: listUserError, data: userList } = await serviceRoleApiClient.listUsers({ + filter: email, + }) + expect(listUserError).toBeNull() + expect(userList).toHaveProperty('users') + expect(userList).toHaveProperty('aud') + + const emails = + userList.users?.map((user: User) => { + return user.email + }) || [] + + expect(emails.length).toEqual(1) + expect(emails).toContain(email) + }) test('getUser() fetches a user by their access_token', async () => { const { email, password } = mockUserCredentials()