diff --git a/.changeset/itchy-rings-spend.md b/.changeset/itchy-rings-spend.md new file mode 100644 index 00000000000..a351d45e6fd --- /dev/null +++ b/.changeset/itchy-rings-spend.md @@ -0,0 +1,5 @@ +--- +'@clerk/backend': patch +--- + +Add `query`, `orderBy`, and `organizationId` to the `SamlConnectionListParams` type. diff --git a/packages/backend/src/api/__tests__/SamlConnectionApi.test.ts b/packages/backend/src/api/__tests__/SamlConnectionApi.test.ts new file mode 100644 index 00000000000..53f780bc557 --- /dev/null +++ b/packages/backend/src/api/__tests__/SamlConnectionApi.test.ts @@ -0,0 +1,72 @@ +import { http, HttpResponse } from 'msw'; +import { describe, expect, it } from 'vitest'; + +import { server, validateHeaders } from '../../mock-server'; +import { createBackendApiClient } from '../factory'; + +describe('SamlConnectionAPI', () => { + const apiClient = createBackendApiClient({ + apiUrl: 'https://api.clerk.test', + secretKey: 'deadbeef', + }); + + describe('getSamlConnectionList', () => { + it('successfully fetches SAML connections with all parameters', async () => { + const mockSamlConnectionsResponse = [ + { + object: 'saml_connection', + id: 'samlc_123', + name: 'Test Connection', + provider: 'saml_custom', + domain: 'test.example.com', + organization_id: 'org_123', + created_at: 1672531200000, + updated_at: 1672531200000, + active: true, + sync_user_attributes: false, + allow_subdomains: false, + allow_idp_initiated: false, + idp_entity_id: 'entity_123', + idp_sso_url: 'https://idp.example.com/sso', + idp_certificate: 'cert_data', + idp_metadata_url: null, + idp_metadata: null, + attribute_mapping: { + user_id: 'userId', + email_address: 'email', + first_name: 'firstName', + last_name: 'lastName', + }, + }, + ]; + + server.use( + http.get( + 'https://api.clerk.test/v1/saml_connections', + validateHeaders(({ request }) => { + const url = new URL(request.url); + expect(url.searchParams.get('query')).toBe('test'); + expect(url.searchParams.get('order_by')).toBe('+created_at'); + expect(url.searchParams.get('limit')).toBe('5'); + expect(url.searchParams.get('offset')).toBe('10'); + expect(url.searchParams.getAll('organization_id')).toEqual(['+org_123', '-org_456']); + return HttpResponse.json({ data: mockSamlConnectionsResponse }); + }), + ), + ); + + const response = await apiClient.samlConnections.getSamlConnectionList({ + query: 'test', + orderBy: '+created_at', + organizationId: ['+org_123', '-org_456'], + limit: 5, + offset: 10, + }); + + expect(response).toHaveLength(1); + expect(response[0].id).toBe('samlc_123'); + expect(response[0].name).toBe('Test Connection'); + expect(response[0].organizationId).toBe('org_123'); + }); + }); +}); diff --git a/packages/backend/src/api/endpoints/SamlConnectionApi.ts b/packages/backend/src/api/endpoints/SamlConnectionApi.ts index 9ac17c2cf2b..cdde3e154ac 100644 --- a/packages/backend/src/api/endpoints/SamlConnectionApi.ts +++ b/packages/backend/src/api/endpoints/SamlConnectionApi.ts @@ -3,13 +3,18 @@ import type { SamlIdpSlug } from '@clerk/types'; import { joinPaths } from '../../util/path'; import type { SamlConnection } from '../resources'; import { AbstractAPI } from './AbstractApi'; +import type { WithSign } from './util-types'; const basePath = '/saml_connections'; type SamlConnectionListParams = { limit?: number; offset?: number; + query?: string; + orderBy?: WithSign<'phone_number' | 'email_address' | 'created_at' | 'first_name' | 'last_name' | 'username'>; + organizationId?: WithSign[]; }; + type CreateSamlConnectionParams = { name: string; provider: SamlIdpSlug;