feat: tenant CA certificate management with staging
Tenants can upload multiple CA certificates for enterprise SSO providers that use private certificate authorities. - New tenant_ca_certs table (V013) with PEM storage in DB - Stage/activate/delete lifecycle per CA cert - Aggregated ca.pem rebuild on activate/delete (atomic .wip swap) - REST API: GET/POST/DELETE on /api/tenant/ca - UI: CA Certificates section on SSO page with upload, activate, remove Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
45
ui/src/api/ca-hooks.ts
Normal file
45
ui/src/api/ca-hooks.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { api } from './client';
|
||||
|
||||
export interface CaCertResponse {
|
||||
id: string;
|
||||
status: string;
|
||||
label: string | null;
|
||||
subject: string;
|
||||
issuer: string;
|
||||
fingerprint: string;
|
||||
notBefore: string;
|
||||
notAfter: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export function useTenantCaCerts() {
|
||||
return useQuery<CaCertResponse[]>({
|
||||
queryKey: ['tenant', 'ca'],
|
||||
queryFn: () => api.get('/tenant/ca'),
|
||||
});
|
||||
}
|
||||
|
||||
export function useStageCaCert() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation<CaCertResponse, Error, FormData>({
|
||||
mutationFn: (formData) => api.post('/tenant/ca', formData),
|
||||
onSuccess: () => qc.invalidateQueries({ queryKey: ['tenant', 'ca'] }),
|
||||
});
|
||||
}
|
||||
|
||||
export function useActivateCaCert() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation<CaCertResponse, Error, string>({
|
||||
mutationFn: (id) => api.post(`/tenant/ca/${id}/activate`),
|
||||
onSuccess: () => qc.invalidateQueries({ queryKey: ['tenant', 'ca'] }),
|
||||
});
|
||||
}
|
||||
|
||||
export function useDeleteCaCert() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation<void, Error, string>({
|
||||
mutationFn: (id) => api.delete(`/tenant/ca/${id}`),
|
||||
onSuccess: () => qc.invalidateQueries({ queryKey: ['tenant', 'ca'] }),
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user