mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-08 07:38:57 +00:00
feat(V2.2): bulk revocation — filter-based fleet-wide certificate revocation
Add POST /api/v1/certificates/bulk-revoke with filter criteria (profile_id, owner_id, agent_id, issuer_id, team_id, certificate_ids), partial-failure tolerance, and audit trail. Includes MCP tool, CLI command (certs bulk-revoke), server-side bulk modal in GUI replacing client-side sequential loop, OpenAPI spec, compliance mapping updates, and 21 new tests (12 service, 7 handler, 1 CLI, 1 frontend). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
updateCertificate,
|
||||
archiveCertificate,
|
||||
revokeCertificate,
|
||||
bulkRevokeCertificates,
|
||||
exportCertificatePEM,
|
||||
downloadCertificatePEM,
|
||||
exportCertificatePKCS12,
|
||||
@@ -288,6 +289,15 @@ describe('API Client', () => {
|
||||
expect(init.method).toBe('POST');
|
||||
expect(JSON.parse(init.body)).toEqual({ reason: 'keyCompromise' });
|
||||
});
|
||||
|
||||
it('bulkRevokeCertificates sends POST with criteria', async () => {
|
||||
mockFetch.mockReturnValueOnce(mockJsonResponse({ total_matched: 3, total_revoked: 2, total_skipped: 1, total_failed: 0 }));
|
||||
await bulkRevokeCertificates({ reason: 'keyCompromise', profile_id: 'prof-tls', certificate_ids: ['mc-1', 'mc-2'] });
|
||||
const [url, init] = mockFetch.mock.calls[0];
|
||||
expect(url).toBe('/api/v1/certificates/bulk-revoke');
|
||||
expect(init.method).toBe('POST');
|
||||
expect(JSON.parse(init.body)).toEqual({ reason: 'keyCompromise', profile_id: 'prof-tls', certificate_ids: ['mc-1', 'mc-2'] });
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Agents ─────────────────────────────────────────
|
||||
|
||||
@@ -95,6 +95,30 @@ export const revokeCertificate = (id: string, reason: string) =>
|
||||
body: JSON.stringify({ reason }),
|
||||
});
|
||||
|
||||
export interface BulkRevokeCriteria {
|
||||
reason: string;
|
||||
profile_id?: string;
|
||||
owner_id?: string;
|
||||
agent_id?: string;
|
||||
issuer_id?: string;
|
||||
team_id?: string;
|
||||
certificate_ids?: string[];
|
||||
}
|
||||
|
||||
export interface BulkRevokeResult {
|
||||
total_matched: number;
|
||||
total_revoked: number;
|
||||
total_skipped: number;
|
||||
total_failed: number;
|
||||
errors?: { certificate_id: string; error: string }[];
|
||||
}
|
||||
|
||||
export const bulkRevokeCertificates = (criteria: BulkRevokeCriteria) =>
|
||||
fetchJSON<BulkRevokeResult>(`${BASE}/certificates/bulk-revoke`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(criteria),
|
||||
});
|
||||
|
||||
// Certificate Export
|
||||
export const exportCertificatePEM = (id: string) =>
|
||||
fetchJSON<{ cert_pem: string; chain_pem: string; full_pem: string }>(`${BASE}/certificates/${id}/export/pem`);
|
||||
|
||||
Reference in New Issue
Block a user