forked from baron/baron-sso
- reproduce the missing n preview with the actual parsedKeys response shape - read nPreview from DevFront instead of the old n field - keep the preview text as provided by backend summaries
316 lines
7.0 KiB
TypeScript
316 lines
7.0 KiB
TypeScript
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<string, unknown>;
|
|
};
|
|
|
|
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<string, unknown>;
|
|
};
|
|
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<string, unknown>;
|
|
};
|
|
|
|
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<IdpConfigCreateRequest>;
|
|
// --- End Federation Types ---
|
|
|
|
export async function fetchClients() {
|
|
const { data } = await apiClient.get<ClientListResponse>("/dev/clients");
|
|
return data;
|
|
}
|
|
|
|
export async function fetchDevStats() {
|
|
const { data } = await apiClient.get<DevStats>("/dev/stats");
|
|
return data;
|
|
}
|
|
|
|
export async function fetchClient(clientId: string) {
|
|
const { data } = await apiClient.get<ClientDetailResponse>(
|
|
`/dev/clients/${clientId}`,
|
|
);
|
|
return data;
|
|
}
|
|
|
|
export async function updateClientStatus(
|
|
clientId: string,
|
|
status: ClientStatus,
|
|
) {
|
|
const { data } = await apiClient.patch<ClientDetailResponse>(
|
|
`/dev/clients/${clientId}/status`,
|
|
{ status },
|
|
);
|
|
return data;
|
|
}
|
|
|
|
export async function createClient(payload: ClientUpsertRequest) {
|
|
const { data } = await apiClient.post<ClientDetailResponse>(
|
|
"/dev/clients",
|
|
payload,
|
|
);
|
|
return data;
|
|
}
|
|
|
|
export async function updateClient(
|
|
clientId: string,
|
|
payload: ClientUpsertRequest,
|
|
) {
|
|
const { data } = await apiClient.put<ClientDetailResponse>(
|
|
`/dev/clients/${clientId}`,
|
|
payload,
|
|
);
|
|
return data;
|
|
}
|
|
|
|
export async function rotateClientSecret(clientId: string) {
|
|
const { data } = await apiClient.post<ClientDetailResponse>(
|
|
`/dev/clients/${clientId}/secret/rotate`,
|
|
);
|
|
return data;
|
|
}
|
|
|
|
export async function refreshHeadlessJwksCache(clientId: string) {
|
|
const { data } = await apiClient.post<ClientDetailResponse>(
|
|
`/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<string, string> = { subject };
|
|
if (clientId) {
|
|
params.client_id = clientId;
|
|
}
|
|
if (status && status !== "all") {
|
|
params.status = status;
|
|
}
|
|
const { data } = await apiClient.get<ConsentListResponse>("/dev/consents", {
|
|
params,
|
|
});
|
|
return data;
|
|
}
|
|
|
|
export async function revokeConsent(subject: string, clientId?: string) {
|
|
const params: Record<string, string> = { 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<IdpConfig[]>(
|
|
`/dev/clients/${clientId}/idps`,
|
|
);
|
|
return data;
|
|
}
|
|
|
|
export async function createIdpConfigForClient(
|
|
payload: IdpConfigCreateRequest,
|
|
) {
|
|
const { data } = await apiClient.post<IdpConfig>(
|
|
`/dev/clients/${payload.client_id}/idps`,
|
|
payload,
|
|
);
|
|
return data;
|
|
}
|
|
|
|
export async function updateIdpConfig(
|
|
clientId: string,
|
|
idpId: string,
|
|
payload: IdpConfigUpdateRequest,
|
|
) {
|
|
const { data } = await apiClient.put<IdpConfig>(
|
|
`/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<DevAuditLogListResponse>(
|
|
"/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<TenantSummary[]>("/dev/my-tenants");
|
|
return data;
|
|
}
|