import apiClient from "./apiClient"; export type ClientStatus = "active" | "inactive"; export type ClientType = "private" | "pkce"; export type ClientSummary = { id: string; name: string; type: ClientType; status: ClientStatus; createdAt?: string; clientSecret?: string; tokenEndpointAuthMethod?: string; jwksUri?: string; redirectUris: string[]; scopes: string[]; metadata?: Record; }; export type ClientListResponse = { items: ClientSummary[]; limit: number; offset: number; }; export type DevStats = { total_clients: number; active_sessions: number; auth_failures_24h: number; }; export type DevAuditLog = { event_id: string; timestamp: string; user_id: string; event_type: string; status: string; ip_address: string; user_agent: string; device_id?: string; details?: string; }; export type DevAuditLogListResponse = { items: DevAuditLog[]; limit: number; cursor?: string; next_cursor?: string; }; export type ClientEndpoints = { discovery: string; issuer: string; authorization: string; token: string; userinfo: string; }; export type ClientDetailResponse = { client: ClientSummary & { clientSecret?: string; metadata?: Record; }; endpoints: ClientEndpoints; headlessJwksCache?: { clientId: string; jwksUri: string; cachedAt: string; expiresAt: string; lastCheckedAt?: string; lastSuccessfulVerificationAt?: string; lastRefreshStatus?: "success" | "failure" | "pending"; lastError?: string; consecutiveFailures?: number; cachedKids?: string[]; etag?: string; lastModified?: string; parsedKeys?: Array<{ kid?: string; kty?: string; use?: string; alg?: string; nPreview?: string; }>; }; }; export type ClientUpsertRequest = { id?: string; name?: string; type?: ClientType; status?: ClientStatus; redirectUris?: string[]; scopes?: string[]; grantTypes?: string[]; responseTypes?: string[]; tokenEndpointAuthMethod?: string; jwksUri?: string; metadata?: Record; }; export type ConsentSummary = { subject: string; userName?: string; clientId: string; clientName?: string; grantedScopes: string[]; authenticatedAt?: string; createdAt: string; deletedAt?: string; status: "active" | "revoked"; tenantId?: string; tenantName?: string; }; export type ConsentListResponse = { items: ConsentSummary[]; }; // --- Federation / IdP Config Types --- export type ProviderType = "oidc" | "saml"; export type IdpConfig = { id: string; client_id: string; // Changed from tenant_id provider_type: ProviderType; display_name: string; status: "active" | "inactive"; issuer_url?: string; // OIDC specific fields oidc_client_id?: string; oidc_client_secret?: string; scopes?: string; // SAML specific fields metadata_url?: string; metadata_xml?: string; entity_id?: string; acs_url?: string; createdAt: string; updatedAt: string; }; export type IdpConfigCreateRequest = Omit< IdpConfig, "id" | "createdAt" | "updatedAt" >; export type IdpConfigUpdateRequest = Partial; // --- End Federation Types --- export async function fetchClients() { const { data } = await apiClient.get("/dev/clients"); return data; } export async function fetchDevStats() { const { data } = await apiClient.get("/dev/stats"); return data; } export async function fetchClient(clientId: string) { const { data } = await apiClient.get( `/dev/clients/${clientId}`, ); return data; } export async function updateClientStatus( clientId: string, status: ClientStatus, ) { const { data } = await apiClient.patch( `/dev/clients/${clientId}/status`, { status }, ); return data; } export async function createClient(payload: ClientUpsertRequest) { const { data } = await apiClient.post( "/dev/clients", payload, ); return data; } export async function updateClient( clientId: string, payload: ClientUpsertRequest, ) { const { data } = await apiClient.put( `/dev/clients/${clientId}`, payload, ); return data; } export async function rotateClientSecret(clientId: string) { const { data } = await apiClient.post( `/dev/clients/${clientId}/secret/rotate`, ); return data; } export async function refreshHeadlessJwksCache(clientId: string) { const { data } = await apiClient.post( `/dev/clients/${clientId}/headless-jwks/refresh`, ); return data; } export async function revokeHeadlessJwksCache(clientId: string) { await apiClient.delete(`/dev/clients/${clientId}/headless-jwks/cache`); } export async function deleteClient(clientId: string) { await apiClient.delete(`/dev/clients/${clientId}`); } export async function fetchConsents( subject: string, clientId?: string, status?: string, ) { const params: Record = { subject }; if (clientId) { params.client_id = clientId; } if (status && status !== "all") { params.status = status; } const { data } = await apiClient.get("/dev/consents", { params, }); return data; } export async function revokeConsent(subject: string, clientId?: string) { const params: Record = { subject }; if (clientId) { params.client_id = clientId; } await apiClient.delete("/dev/consents", { params }); } // --- Federation / IdP Config API Calls --- export async function listIdpConfigsForClient(clientId: string) { const { data } = await apiClient.get( `/dev/clients/${clientId}/idps`, ); return data; } export async function createIdpConfigForClient( payload: IdpConfigCreateRequest, ) { const { data } = await apiClient.post( `/dev/clients/${payload.client_id}/idps`, payload, ); return data; } export async function updateIdpConfig( clientId: string, idpId: string, payload: IdpConfigUpdateRequest, ) { const { data } = await apiClient.put( `/dev/clients/${clientId}/idps/${idpId}`, payload, ); return data; } export async function deleteIdpConfig(clientId: string, idpId: string) { await apiClient.delete(`/dev/clients/${clientId}/idps/${idpId}`); } export async function fetchDevAuditLogs( limit = 50, cursor?: string, filters?: { action?: string; client_id?: string; status?: string; tenant_id?: string; }, ) { const { data } = await apiClient.get( "/dev/audit-logs", { params: { limit, cursor, action: filters?.action, client_id: filters?.client_id, status: filters?.status, tenant_id: filters?.tenant_id, }, }, ); return data; } export type TenantSummary = { id: string; name: string; slug: string; }; export async function fetchMyTenants() { const { data } = await apiClient.get("/dev/my-tenants"); return data; }