mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-12 19:57:37 +00:00
e3b3c3b857
The scan detail sheet fetches a capped page of vulnerabilities for display, then told operators to "Export CSV for the complete list". The CSV writer only serialized the rows already in memory, so for a scan with more findings than the page cap the CSV silently dropped everything past the cap: the recovery path the notice promised did not exist. Export now pages past the API's per-request cap and serializes every row when the loaded set is short of the total, falling back to the in-memory rows when they are already complete. The CSV action shows a spinner and disables while the export runs.
29 lines
1.2 KiB
TypeScript
29 lines
1.2 KiB
TypeScript
import { apiFetch } from '@/lib/api';
|
|
import type { VulnerabilityDetail } from '@/types/security';
|
|
|
|
/**
|
|
* Every vulnerability row for a scan, paging past the API's per-request cap
|
|
* (the backend clamps a single page to 1000 rows). The detail table renders
|
|
* only a capped page, so the CSV export relies on this to make good on its
|
|
* "complete list" promise for scans with thousands of findings. Unfiltered by
|
|
* severity on purpose: the CSV is the full record, not the current view. A
|
|
* short page also ends the loop, so an over-reported `total` cannot spin it.
|
|
*/
|
|
export async function fetchAllScanVulnerabilities(
|
|
scanId: number,
|
|
): Promise<VulnerabilityDetail[]> {
|
|
const all: VulnerabilityDetail[] = [];
|
|
const pageSize = 1000;
|
|
for (let offset = 0; ; offset += pageSize) {
|
|
const res = await apiFetch(
|
|
`/security/scans/${scanId}/vulnerabilities?limit=${pageSize}&offset=${offset}`,
|
|
);
|
|
if (!res.ok) throw new Error('Failed to fetch the full vulnerability list');
|
|
const data = await res.json();
|
|
const items: VulnerabilityDetail[] = Array.isArray(data.items) ? data.items : [];
|
|
all.push(...items);
|
|
if (items.length < pageSize || all.length >= (data.total ?? all.length)) break;
|
|
}
|
|
return all;
|
|
}
|