mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 20:42:02 +00:00
refactor: remove getScansByFields and use getScans with flexible filters
This commit is contained in:
+10
-48
@@ -16,6 +16,12 @@ export const getScans = async ({
|
||||
sort = "",
|
||||
filters = {},
|
||||
pageSize = 10,
|
||||
}: {
|
||||
page?: number;
|
||||
query?: string;
|
||||
sort?: string;
|
||||
filters?: Record<string, string | number | boolean>;
|
||||
pageSize?: number;
|
||||
}) => {
|
||||
const headers = await getAuthHeaders({ contentType: false });
|
||||
|
||||
@@ -28,23 +34,18 @@ export const getScans = async ({
|
||||
if (query) url.searchParams.append("filter[search]", query);
|
||||
if (sort) url.searchParams.append("sort", sort);
|
||||
|
||||
// Handle multiple filters
|
||||
// Add dynamic filters (e.g., "filter[state]", "fields[scans]")
|
||||
Object.entries(filters).forEach(([key, value]) => {
|
||||
if (key !== "filter[search]") {
|
||||
url.searchParams.append(key, String(value));
|
||||
}
|
||||
url.searchParams.append(key, String(value));
|
||||
});
|
||||
|
||||
try {
|
||||
const scans = await fetch(url.toString(), {
|
||||
headers,
|
||||
});
|
||||
const data = await scans.json();
|
||||
const response = await fetch(url.toString(), { headers });
|
||||
const data = await response.json();
|
||||
const parsedData = parseStringify(data);
|
||||
revalidatePath("/scans");
|
||||
return parsedData;
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error("Error fetching scans:", error);
|
||||
return undefined;
|
||||
}
|
||||
@@ -260,45 +261,6 @@ export const getExportsZip = async (scanId: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const getScansByFields = async (
|
||||
fields: string = "state",
|
||||
filters = {},
|
||||
) => {
|
||||
const headers = await getAuthHeaders({ contentType: false });
|
||||
|
||||
const url = new URL(`${apiBaseUrl}/scans`);
|
||||
|
||||
// Request only the necessary fields to optimize the response
|
||||
url.searchParams.append("fields[scans]", fields);
|
||||
|
||||
Object.entries(filters).forEach(([key, value]) => {
|
||||
url.searchParams.append(key, String(value));
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await fetch(url.toString(), {
|
||||
headers,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
try {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData?.message || "Failed to fetch scans by state");
|
||||
} catch {
|
||||
throw new Error("Failed to fetch scans by state");
|
||||
}
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
return parseStringify(data);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error("Error fetching scans by state:", error);
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
export const getComplianceCsv = async (
|
||||
scanId: string,
|
||||
complianceId: string,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { format, parseISO } from "date-fns";
|
||||
import { Suspense } from "react";
|
||||
|
||||
import { getResourceFields, getResources } from "@/actions/resources";
|
||||
import { getScansByFields } from "@/actions/scans";
|
||||
import { getScans } from "@/actions/scans";
|
||||
import { FilterControls } from "@/components/filters";
|
||||
import { SkeletonTableResources } from "@/components/resources/skeleton/skeleton-table-resources";
|
||||
import { ColumnResources } from "@/components/resources/table/column-resources";
|
||||
@@ -41,9 +41,11 @@ export default async function Resources({
|
||||
),
|
||||
};
|
||||
|
||||
// Fetch scans data latest date not fully done
|
||||
const scansData = await getScansByFields("inserted_at", {
|
||||
"filter[state]": "completed",
|
||||
const scansData = await getScans({
|
||||
filters: {
|
||||
"filter[state]": "completed",
|
||||
"fields[scans]": "inserted_at",
|
||||
},
|
||||
});
|
||||
|
||||
if (scansData.data?.length !== 0) {
|
||||
@@ -161,8 +163,11 @@ const SSRDataTable = async ({
|
||||
};
|
||||
|
||||
// Fetch scans data latest date
|
||||
const scansData = await getScansByFields("inserted_at", {
|
||||
"filter[state]": "completed",
|
||||
const scansData = await getScans({
|
||||
filters: {
|
||||
"filter[state]": "completed",
|
||||
"fields[scans]": "inserted_at",
|
||||
},
|
||||
});
|
||||
|
||||
if (scansData.data?.length !== 0) {
|
||||
|
||||
@@ -123,7 +123,13 @@ const SSRDataTableScans = async ({
|
||||
const query = (filters["filter[search]"] as string) || "";
|
||||
|
||||
// Fetch scans data
|
||||
const scansData = await getScans({ query, page, sort, filters, pageSize });
|
||||
const scansData = await getScans({
|
||||
query,
|
||||
page,
|
||||
sort,
|
||||
filters: filters as Record<string, string | number | boolean>,
|
||||
pageSize,
|
||||
});
|
||||
|
||||
// Handle expanded scans data
|
||||
const expandedScansData = await Promise.all(
|
||||
|
||||
@@ -131,10 +131,10 @@ export const ResourceDetail = ({
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
{/* Finding Details section */}
|
||||
{/* Finding associated with this resource section */}
|
||||
<div>
|
||||
<h2 className="line-clamp-2 text-lg font-medium leading-tight text-gray-800 dark:text-prowler-theme-pale/90">
|
||||
Findings Details
|
||||
<h2 className="text-md line-clamp-2 font-medium leading-tight text-gray-800 dark:text-prowler-theme-pale/90">
|
||||
Findings associated with this resource
|
||||
</h2>
|
||||
</div>
|
||||
{isLoading ? (
|
||||
|
||||
+1
-143
@@ -1,7 +1,7 @@
|
||||
import { LucideIcon } from "lucide-react";
|
||||
import { SVGProps } from "react";
|
||||
|
||||
import { ProviderType } from "./providers";
|
||||
import { ProviderProps, ProviderType } from "./providers";
|
||||
|
||||
export type IconSvgProps = SVGProps<SVGSVGElement> & {
|
||||
size?: number;
|
||||
@@ -704,145 +704,3 @@ export interface UserProps {
|
||||
dateAdded: string;
|
||||
status: "active" | "inactive";
|
||||
}
|
||||
|
||||
export interface ResourceProps {
|
||||
type: "resources";
|
||||
id: string;
|
||||
attributes: {
|
||||
inserted_at: string;
|
||||
updated_at: string;
|
||||
uid: string;
|
||||
name: string;
|
||||
region: string;
|
||||
service: string;
|
||||
tags: Record<string, string>;
|
||||
type: string;
|
||||
};
|
||||
relationships: {
|
||||
provider: {
|
||||
data: {
|
||||
type: "providers";
|
||||
id: string;
|
||||
attributes: {
|
||||
inserted_at: string;
|
||||
updated_at: string;
|
||||
provider: string;
|
||||
uid: string;
|
||||
alias: string | null;
|
||||
connection: {
|
||||
connected: boolean;
|
||||
last_checked_at: string;
|
||||
};
|
||||
};
|
||||
relationships: {
|
||||
secret: {
|
||||
data: {
|
||||
type: "provider-secrets";
|
||||
id: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
links: {
|
||||
self: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
findings: {
|
||||
meta: {
|
||||
count: number;
|
||||
};
|
||||
data: {
|
||||
type: "findings";
|
||||
id: string;
|
||||
attributes: { status: string };
|
||||
}[];
|
||||
};
|
||||
};
|
||||
links: {
|
||||
self: string;
|
||||
};
|
||||
}
|
||||
interface Provider {
|
||||
type: "providers" | "findings";
|
||||
id: string;
|
||||
attributes: {
|
||||
uid: string;
|
||||
delta: string;
|
||||
status: "PASS" | "FAIL" | "MANUAL";
|
||||
status_extended: string;
|
||||
severity: "informational" | "low" | "medium" | "high" | "critical";
|
||||
check_id: string;
|
||||
check_metadata: CheckMetadata;
|
||||
raw_result: Record<string, any>;
|
||||
inserted_at: string;
|
||||
updated_at: string;
|
||||
first_seen_at: string;
|
||||
muted: boolean;
|
||||
};
|
||||
relationships: {
|
||||
secret: {
|
||||
data: {
|
||||
type: string;
|
||||
id: string;
|
||||
};
|
||||
};
|
||||
scan: {
|
||||
data: {
|
||||
type: string;
|
||||
id: string;
|
||||
};
|
||||
};
|
||||
provider_groups: {
|
||||
meta: {
|
||||
count: number;
|
||||
};
|
||||
data: [];
|
||||
};
|
||||
};
|
||||
links: {
|
||||
self: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface CheckMetadata {
|
||||
risk: string;
|
||||
notes: string;
|
||||
checkid: string;
|
||||
provider: string;
|
||||
severity: string;
|
||||
checktype: string[];
|
||||
dependson: string[];
|
||||
relatedto: string[];
|
||||
categories: string[];
|
||||
checktitle: string;
|
||||
compliance: any;
|
||||
relatedurl: string;
|
||||
description: string;
|
||||
remediation: {
|
||||
code: {
|
||||
cli: string;
|
||||
other: string;
|
||||
nativeiac: string;
|
||||
terraform: string;
|
||||
};
|
||||
recommendation: {
|
||||
url: string;
|
||||
text: string;
|
||||
};
|
||||
};
|
||||
servicename: string;
|
||||
checkaliases: string[];
|
||||
resourcetype: string;
|
||||
subservicename: string;
|
||||
resourceidtemplate: string;
|
||||
}
|
||||
|
||||
interface Meta {
|
||||
version: string;
|
||||
}
|
||||
|
||||
export interface ResourceApiResponse {
|
||||
data: ResourceProps;
|
||||
included: Provider[];
|
||||
meta: Meta;
|
||||
}
|
||||
|
||||
@@ -3,3 +3,4 @@ export * from "./components";
|
||||
export * from "./filters";
|
||||
export * from "./formSchemas";
|
||||
export * from "./providers";
|
||||
export * from "./resources";
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
export interface ResourceProps {
|
||||
type: "resources";
|
||||
id: string;
|
||||
attributes: {
|
||||
inserted_at: string;
|
||||
updated_at: string;
|
||||
uid: string;
|
||||
name: string;
|
||||
region: string;
|
||||
service: string;
|
||||
tags: Record<string, string>;
|
||||
type: string;
|
||||
};
|
||||
relationships: {
|
||||
provider: {
|
||||
data: {
|
||||
type: "providers";
|
||||
id: string;
|
||||
attributes: {
|
||||
inserted_at: string;
|
||||
updated_at: string;
|
||||
provider: string;
|
||||
uid: string;
|
||||
alias: string | null;
|
||||
connection: {
|
||||
connected: boolean;
|
||||
last_checked_at: string;
|
||||
};
|
||||
};
|
||||
relationships: {
|
||||
secret: {
|
||||
data: {
|
||||
type: "provider-secrets";
|
||||
id: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
links: {
|
||||
self: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
findings: {
|
||||
meta: {
|
||||
count: number;
|
||||
};
|
||||
data: {
|
||||
type: "findings";
|
||||
id: string;
|
||||
attributes: { status: string };
|
||||
}[];
|
||||
};
|
||||
};
|
||||
links: {
|
||||
self: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface ResourceItemProps {
|
||||
type: "providers" | "findings";
|
||||
id: string;
|
||||
attributes: {
|
||||
uid: string;
|
||||
delta: string;
|
||||
status: "PASS" | "FAIL" | "MANUAL";
|
||||
status_extended: string;
|
||||
severity: "informational" | "low" | "medium" | "high" | "critical";
|
||||
check_id: string;
|
||||
check_metadata: CheckMetadataProps;
|
||||
raw_result: Record<string, any>;
|
||||
inserted_at: string;
|
||||
updated_at: string;
|
||||
first_seen_at: string;
|
||||
muted: boolean;
|
||||
};
|
||||
relationships: {
|
||||
secret: {
|
||||
data: {
|
||||
type: string;
|
||||
id: string;
|
||||
};
|
||||
};
|
||||
scan: {
|
||||
data: {
|
||||
type: string;
|
||||
id: string;
|
||||
};
|
||||
};
|
||||
provider_groups: {
|
||||
meta: {
|
||||
count: number;
|
||||
};
|
||||
data: [];
|
||||
};
|
||||
};
|
||||
links: {
|
||||
self: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface CheckMetadataProps {
|
||||
risk: string;
|
||||
notes: string;
|
||||
checkid: string;
|
||||
provider: string;
|
||||
severity: string;
|
||||
checktype: string[];
|
||||
dependson: string[];
|
||||
relatedto: string[];
|
||||
categories: string[];
|
||||
checktitle: string;
|
||||
compliance: any;
|
||||
relatedurl: string;
|
||||
description: string;
|
||||
remediation: {
|
||||
code: {
|
||||
cli: string;
|
||||
other: string;
|
||||
nativeiac: string;
|
||||
terraform: string;
|
||||
};
|
||||
recommendation: {
|
||||
url: string;
|
||||
text: string;
|
||||
};
|
||||
};
|
||||
servicename: string;
|
||||
checkaliases: string[];
|
||||
resourcetype: string;
|
||||
subservicename: string;
|
||||
resourceidtemplate: string;
|
||||
}
|
||||
|
||||
interface Meta {
|
||||
version: string;
|
||||
}
|
||||
|
||||
export interface ResourceApiResponse {
|
||||
data: ResourceProps;
|
||||
included: ResourceItemProps[];
|
||||
meta: Meta;
|
||||
}
|
||||
Reference in New Issue
Block a user