diff --git a/.changeset/shaky-otters-care.md b/.changeset/shaky-otters-care.md new file mode 100644 index 00000000000..b8a9919ec27 --- /dev/null +++ b/.changeset/shaky-otters-care.md @@ -0,0 +1,7 @@ +--- +'@clerk/backend': minor +--- + +Add `lastSignInAtAfter` and `lastSignInAtBefore` filters to the Users API list and count endpoints. + +These parameters are supported by `users.getUserList()` and are forwarded to `/v1/users` and `/v1/users/count` to filter users by last sign-in timestamp. diff --git a/packages/backend/src/api/__tests__/factory.test.ts b/packages/backend/src/api/__tests__/factory.test.ts index bc73d4a207d..337581f52cb 100644 --- a/packages/backend/src/api/__tests__/factory.test.ts +++ b/packages/backend/src/api/__tests__/factory.test.ts @@ -59,6 +59,40 @@ describe('api.client', () => { expect(totalCount).toBe(2); }); + it('executes users.getUserList() with last_sign_in_at filters', async () => { + const afterTimestamp = 1640000000; + const beforeTimestamp = 1700000000; + + server.use( + http.get( + `https://api.clerk.test/v1/users`, + validateHeaders(({ request }) => { + const url = new URL(request.url); + expect(url.searchParams.get('last_sign_in_at_after')).toBe(afterTimestamp.toString()); + expect(url.searchParams.get('last_sign_in_at_before')).toBe(beforeTimestamp.toString()); + return HttpResponse.json([userJson]); + }), + ), + http.get( + `https://api.clerk.test/v1/users/count`, + validateHeaders(({ request }) => { + const url = new URL(request.url); + expect(url.searchParams.get('last_sign_in_at_after')).toBe(afterTimestamp.toString()); + expect(url.searchParams.get('last_sign_in_at_before')).toBe(beforeTimestamp.toString()); + return HttpResponse.json({ object: 'total_count', total_count: 1 }); + }), + ), + ); + + const { data, totalCount } = await apiClient.users.getUserList({ + lastSignInAtAfter: afterTimestamp, + lastSignInAtBefore: beforeTimestamp, + }); + + expect(data.length).toBe(1); + expect(totalCount).toBe(1); + }); + it('executes a successful backend API request for a paginated response', async () => { server.use( http.get( diff --git a/packages/backend/src/api/endpoints/UserApi.ts b/packages/backend/src/api/endpoints/UserApi.ts index 38f31670827..509b5c5d256 100644 --- a/packages/backend/src/api/endpoints/UserApi.ts +++ b/packages/backend/src/api/endpoints/UserApi.ts @@ -41,6 +41,8 @@ type UserListParams = ClerkPaginationRequest< | 'last_sign_in_at' >; last_active_at_since?: number; + lastSignInAtAfter?: number; + lastSignInAtBefore?: number; organizationId?: string[]; } >;