From c07eeac7cfc56aa26f6357bd4a27865da414df1c Mon Sep 17 00:00:00 2001 From: Daniel Kantor Date: Fri, 24 Jan 2025 18:26:05 +0100 Subject: [PATCH] display detected problem properly --- src/components/AlertsTable.tsx | 37 ++++++++++++++++++- src/lib/utils.ts | 12 ++++++ src/routes/__tests__/route-dashboard.test.tsx | 23 ++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/components/AlertsTable.tsx b/src/components/AlertsTable.tsx index 1301bbc0..d25a6db2 100644 --- a/src/components/AlertsTable.tsx +++ b/src/components/AlertsTable.tsx @@ -16,8 +16,12 @@ import { import { Switch } from "@stacklok/ui-kit"; import { AlertConversation, QuestionType } from "@/api/generated"; import { Tooltip, TooltipTrigger } from "@stacklok/ui-kit"; -import { sanitizeQuestionPrompt, parsingPromptText } from "@/lib/utils"; -import { Search } from "lucide-react"; +import { + sanitizeQuestionPrompt, + parsingPromptText, + getIssueDetectedType, +} from "@/lib/utils"; +import { KeyRoundIcon, PackageX, Search } from "lucide-react"; import { useAlertSearch } from "@/hooks/useAlertSearch"; import { useCallback } from "react"; import { useNavigate, useSearchParams } from "react-router-dom"; @@ -50,6 +54,29 @@ function TypeCellContent({ alert }: { alert: AlertConversation }) { } } +function IssueDetectedCellContent({ alert }: { alert: AlertConversation }) { + const issueDetected = getIssueDetectedType(alert); + + switch (issueDetected) { + case "leaked_secret": + return ( + <> + + Blocked secret exposure + + ); + case "malicious_package": + return ( + <> + + Blocked malicious package + + ); + default: + return ""; + } +} + export function AlertsTable() { const { isMaliciousFilterActive, @@ -154,6 +181,7 @@ export function AlertsTable() { Type Event + Issue Detected @@ -174,6 +202,11 @@ export function AlertsTable() { {getTitle(alert)} + +
+ +
+
))}
diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 886881d1..262d785e 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -175,3 +175,15 @@ export function getMaliciousPackage( return null; } + +export function getIssueDetectedType( + alert: AlertConversation, +): "malicious_package" | "leaked_secret" { + const maliciousPackage = getMaliciousPackage(alert.trigger_string); + + if (maliciousPackage !== null && typeof maliciousPackage === "object") { + return "malicious_package"; + } + + return "leaked_secret"; +} diff --git a/src/routes/__tests__/route-dashboard.test.tsx b/src/routes/__tests__/route-dashboard.test.tsx index 6005e6b6..9e8d8c6f 100644 --- a/src/routes/__tests__/route-dashboard.test.tsx +++ b/src/routes/__tests__/route-dashboard.test.tsx @@ -156,6 +156,12 @@ describe("Dashboard", () => { }), ).toBeVisible(); + expect( + screen.getByRole("columnheader", { + name: /issue detected/i, + }), + ).toBeVisible(); + expect( screen.getByRole("switch", { name: /malicious packages/i, @@ -169,6 +175,11 @@ describe("Dashboard", () => { expect(within(firstRow).getByText(/chat/i)).toBeVisible(); expect(within(firstRow).getByText(/[0-9]+.*ago/i)).toBeVisible(); + expect( + screen.getAllByRole("gridcell", { + name: /blocked secret exposure/i, + }).length, + ).toBeGreaterThanOrEqual(1); }); it("should render malicious pkg", async () => { @@ -188,6 +199,12 @@ describe("Dashboard", () => { /codegate-context-retriever/i, ), ).toBeVisible(); + + expect( + screen.getByRole("gridcell", { + name: /blocked malicious package/i, + }), + ).toBeVisible(); }); it("renders event column", async () => { @@ -224,6 +241,12 @@ describe("Dashboard", () => { expect(screen.getByTestId(/alerts-count/i)).toHaveTextContent("1"), ); + expect( + screen.queryAllByRole("gridcell", { + name: /blocked secret exposure/i, + }).length, + ).toBe(0); + userEvent.click( screen.getByRole("switch", { name: /malicious packages/i,