diff --git a/packages/core/auth-js/src/GoTrueAdminApi.ts b/packages/core/auth-js/src/GoTrueAdminApi.ts index d4bc3a5081..c310538859 100644 --- a/packages/core/auth-js/src/GoTrueAdminApi.ts +++ b/packages/core/auth-js/src/GoTrueAdminApi.ts @@ -547,7 +547,7 @@ 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 page = parseInt(link.split(';')[0].match(/[?&]page=(\d+)/)?.[1] ?? '', 10) const rel = JSON.parse(link.split(';')[1].split('=')[1]) pagination[`${rel}Page`] = page }) @@ -934,7 +934,7 @@ 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 page = parseInt(link.split(';')[0].match(/[?&]page=(\d+)/)?.[1] ?? '', 10) const rel = JSON.parse(link.split(';')[1].split('=')[1]) pagination[`${rel}Page`] = page }) diff --git a/packages/core/auth-js/test/GoTrueAdminApi.pagination.test.ts b/packages/core/auth-js/test/GoTrueAdminApi.pagination.test.ts new file mode 100644 index 0000000000..bbfb58450d --- /dev/null +++ b/packages/core/auth-js/test/GoTrueAdminApi.pagination.test.ts @@ -0,0 +1,32 @@ +import { MockServer } from 'jest-mock-server' +import GoTrueAdminApi from '../src/GoTrueAdminApi' + +describe('GoTrueAdminApi listUsers() pagination', () => { + const server = new MockServer() + + beforeAll(async () => await server.start()) + afterAll(async () => await server.stop()) + beforeEach(() => server.reset()) + + test('parses multi-digit page numbers from the Link header', async () => { + const base = server.getURL().toString().replace(/\/$/, '') + + server.get('/admin/users').mockImplementation((ctx) => { + ctx.set( + 'Link', + `<${base}/admin/users?page=10&per_page=50>; rel="next", ` + + `<${base}/admin/users?page=23&per_page=50>; rel="last"` + ) + ctx.set('x-total-count', '1150') + ctx.status = 200 + ctx.body = { users: [], aud: 'authenticated' } + }) + + const admin = new GoTrueAdminApi({ url: base, headers: {} }) + const { data, error } = await admin.listUsers({ page: 9, perPage: 50 }) + + expect(error).toBeNull() + // Regression: the old `.substring(0, 1)` parse truncated these to 1 and 2. + expect(data).toMatchObject({ nextPage: 10, lastPage: 23, total: 1150 }) + }) +})