"use client"; import { Card, CardBody, CardHeader } from "@heroui/card"; import { Chip } from "@heroui/chip"; import { format } from "date-fns"; import { PlusIcon, Trash2Icon } from "lucide-react"; import { useState } from "react"; import { deleteIntegration, testIntegrationConnection, updateIntegration, } from "@/actions/integrations"; import { AWSSecurityHubIcon } from "@/components/icons/services/IconServices"; import { IntegrationActionButtons, IntegrationCardHeader, IntegrationSkeleton, } from "@/components/integrations/shared"; import { useToast } from "@/components/ui"; import { CustomAlertModal, CustomButton } from "@/components/ui/custom"; import { DataTablePagination } from "@/components/ui/table/data-table-pagination"; import { triggerTestConnectionWithDelay } from "@/lib/integrations/test-connection-helper"; import { MetaDataProps } from "@/types"; import { IntegrationProps } from "@/types/integrations"; import { ProviderProps } from "@/types/providers"; import { SecurityHubIntegrationForm } from "./security-hub-integration-form"; interface SecurityHubIntegrationsManagerProps { integrations: IntegrationProps[]; providers: ProviderProps[]; metadata?: MetaDataProps; } export const SecurityHubIntegrationsManager = ({ integrations, providers, metadata, }: SecurityHubIntegrationsManagerProps) => { const [isModalOpen, setIsModalOpen] = useState(false); const [editingIntegration, setEditingIntegration] = useState(null); const [editMode, setEditMode] = useState< "configuration" | "credentials" | null >(null); const [isDeleting, setIsDeleting] = useState(null); const [isTesting, setIsTesting] = useState(null); const [isOperationLoading, setIsOperationLoading] = useState(false); const [isDeleteOpen, setIsDeleteOpen] = useState(false); const [integrationToDelete, setIntegrationToDelete] = useState(null); const { toast } = useToast(); const handleAddIntegration = () => { setEditingIntegration(null); setEditMode(null); setIsModalOpen(true); }; const handleEditConfiguration = (integration: IntegrationProps) => { setEditingIntegration(integration); setEditMode("configuration"); setIsModalOpen(true); }; const handleEditCredentials = (integration: IntegrationProps) => { setEditingIntegration(integration); setEditMode("credentials"); setIsModalOpen(true); }; const handleOpenDeleteModal = (integration: IntegrationProps) => { setIntegrationToDelete(integration); setIsDeleteOpen(true); }; const handleDeleteIntegration = async (id: string) => { setIsDeleting(id); try { const result = await deleteIntegration(id, "aws_security_hub"); if (result.success) { toast({ title: "Success!", description: "Security Hub integration deleted successfully.", }); } else if (result.error) { toast({ variant: "destructive", title: "Delete Failed", description: result.error, }); } } catch (error) { toast({ variant: "destructive", title: "Error", description: "Failed to delete Security Hub integration. Please try again.", }); } finally { setIsDeleting(null); setIsDeleteOpen(false); setIntegrationToDelete(null); } }; const handleTestConnection = async (id: string) => { setIsTesting(id); try { const result = await testIntegrationConnection(id); if (result.success) { toast({ title: "Connection test successful!", description: result.message || "Connection test completed successfully.", }); } else if (result.error) { toast({ variant: "destructive", title: "Connection test failed", description: result.error, }); } } catch (error) { toast({ variant: "destructive", title: "Error", description: "Failed to test connection. Please try again.", }); } finally { setIsTesting(null); } }; const handleToggleEnabled = async (integration: IntegrationProps) => { try { const newEnabledState = !integration.attributes.enabled; const formData = new FormData(); formData.append( "integration_type", integration.attributes.integration_type, ); formData.append("enabled", JSON.stringify(newEnabledState)); const result = await updateIntegration(integration.id, formData); if (result && "success" in result) { toast({ title: "Success!", description: `Integration ${newEnabledState ? "enabled" : "disabled"} successfully.`, }); // If enabling, trigger test connection automatically if (newEnabledState) { setIsTesting(integration.id); triggerTestConnectionWithDelay( integration.id, true, "security_hub", toast, 500, () => { setIsTesting(null); }, ); } } else if (result && "error" in result) { toast({ variant: "destructive", title: "Toggle Failed", description: result.error, }); } } catch (error) { toast({ variant: "destructive", title: "Error", description: "Failed to toggle integration. Please try again.", }); } }; const handleModalClose = () => { setIsModalOpen(false); setEditingIntegration(null); setEditMode(null); }; const handleFormSuccess = async ( integrationId?: string, shouldTestConnection?: boolean, ) => { // Close the modal immediately setIsModalOpen(false); setEditingIntegration(null); setEditMode(null); setIsOperationLoading(true); // Set testing state for server-triggered test connections if (integrationId && shouldTestConnection) { setIsTesting(integrationId); } // Trigger test connection if needed triggerTestConnectionWithDelay( integrationId, shouldTestConnection, "security_hub", toast, 200, () => { // Clear testing state when server-triggered test completes setIsTesting(null); }, ); // Reset loading state after a short delay to show the skeleton briefly setTimeout(() => { setIsOperationLoading(false); }, 1500); }; const getProviderDetails = (integration: IntegrationProps) => { const providerRelationships = integration.relationships?.providers?.data; if (!providerRelationships || providerRelationships.length === 0) { return { displayName: "Unknown Account", accountId: null }; } // Security Hub should only have one provider const providerId = providerRelationships[0].id; const provider = providers.find((p) => p.id === providerId); if (!provider) { return { displayName: "Unknown Account", accountId: null }; } return { displayName: provider.attributes.alias || provider.attributes.uid, accountId: provider.attributes.uid, alias: provider.attributes.alias, }; }; const getEnabledRegions = (integration: IntegrationProps) => { const regions = integration.attributes.configuration.regions; if (!regions || typeof regions !== "object") return []; return Object.entries(regions) .filter(([_, enabled]) => enabled === true) .map(([region]) => region) .sort(); }; return ( <>
{ setIsDeleteOpen(false); setIntegrationToDelete(null); }} isDisabled={isDeleting !== null} > Cancel } onPress={() => integrationToDelete && handleDeleteIntegration(integrationToDelete.id) } > {isDeleting ? "Deleting..." : "Delete"}

Configured Security Hub Integrations

{integrations.length === 0 ? "Not configured yet" : `${integrations.length} integration${integrations.length !== 1 ? "s" : ""} configured`}

} onPress={handleAddIntegration} ariaLabel="Add integration" > Add Integration
{isOperationLoading ? ( } title="AWS Security Hub" subtitle="Send security findings to AWS Security Hub." /> ) : integrations.length > 0 ? (
{integrations.map((integration) => { const enabledRegions = getEnabledRegions(integration); const providerDetails = getProviderDetails(integration); return ( } title={providerDetails.displayName} subtitle={ providerDetails.accountId && providerDetails.alias ? `Account ID: ${providerDetails.accountId}` : "AWS Security Hub Integration" } chips={[ { label: integration.attributes.configuration .send_only_fails ? "Failed Only" : "All Findings", }, { label: integration.attributes.configuration .archive_previous_findings ? "Archive Previous" : "Keep Previous", }, ]} connectionStatus={{ connected: integration.attributes.connected, }} />
{enabledRegions.length > 0 && (
{enabledRegions.map((region) => ( {region} ))}
)}
{integration.attributes.updated_at && (

Last updated:{" "} {format( new Date(integration.attributes.updated_at), "yyyy/MM/dd", )}

)}
); })}
) : null} {metadata && integrations.length > 0 && (
)}
); };