mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 20:42:02 +00:00
94ee24071a
Co-authored-by: alejandrobailo <alejandrobailo94@gmail.com>
131 lines
5.4 KiB
TypeScript
131 lines
5.4 KiB
TypeScript
/**
|
|
* Sort presets for findings-shaped endpoints.
|
|
*
|
|
* The Prowler API exposes two families of findings endpoints with INVERTED
|
|
* sort semantics for the same human intent. Reading them wrong inverts the
|
|
* triage order silently — a bug that has shipped more than once.
|
|
*
|
|
* ─── Family A: plain findings ─────────────────────────────────────────────
|
|
* `/findings`, `/findings/latest`
|
|
* `FindingViewSet.ordering_fields` (api/v1/views.py) maps `status` and
|
|
* `severity` straight to the Postgres ENUM columns. Postgres sorts ENUMs
|
|
* by DECLARATION order:
|
|
* severity: critical, high, medium, low, informational → ASC = critical first
|
|
* status: FAIL, PASS, MANUAL → ASC = FAIL first
|
|
* Use the bare token. NO minus prefix on `status` or `severity`.
|
|
* `delta` is NOT in `ordering_fields` — sorting by delta is unsupported.
|
|
*
|
|
* ─── Family B: finding-groups ─────────────────────────────────────────────
|
|
* `/finding-groups`, `/finding-groups/latest`, `/finding-groups/{id}/resources`
|
|
* `_FINDING_GROUP_SORT_MAP` and `_RESOURCE_SORT_MAP` (api/v1/views.py)
|
|
* REMAP the public sort keys to computed integer columns:
|
|
* severity → severity_order (5=critical … 1=informational)
|
|
* status → status_order (3=FAIL, 2=PASS, 1=MANUAL)
|
|
* delta → delta_order (2=new, 1=changed, 0=otherwise)
|
|
* Higher integer = more important. PREFIX with `-` to put FAIL/critical/new first.
|
|
*
|
|
* The two families look identical from the outside (`sort=...`) but require
|
|
* opposite tokens. Always import from this file. Never hard-code.
|
|
*/
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Family A: plain findings (Postgres ENUM — no minus on status/severity)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const FINDINGS_FAIL_FIRST = "status";
|
|
export const FINDINGS_SEVERITY_HIGH_FIRST = "severity";
|
|
export const FINDINGS_RECENT_INSERT = "-inserted_at";
|
|
export const FINDINGS_RECENT_UPDATE = "-updated_at";
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Family B: finding-groups (computed integer — minus on status/severity/delta)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const FG_FAIL_FIRST = "-status";
|
|
export const FG_SEVERITY_HIGH_FIRST = "-severity";
|
|
export const FG_DELTA_NEW_FIRST = "-delta";
|
|
export const FG_RECENT_LAST_SEEN = "-last_seen_at";
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Composition
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const composeSort = (...tokens: string[]): string => tokens.join(",");
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Presets — Family A
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Default for plain-findings tables WITHOUT a server-side `filter[status]`.
|
|
* FAIL rows first, then critical→informational, then most recent.
|
|
* Delta is intentionally omitted — `/findings` does not accept `delta` as a
|
|
* sort field (see FindingViewSet.ordering_fields).
|
|
*/
|
|
export const FINDINGS_DEFAULT_SORT = composeSort(
|
|
FINDINGS_FAIL_FIRST,
|
|
FINDINGS_SEVERITY_HIGH_FIRST,
|
|
FINDINGS_RECENT_INSERT,
|
|
);
|
|
|
|
/**
|
|
* Default for plain-findings tables that ALREADY apply `filter[status]=FAIL`
|
|
* (or equivalent) server-side. Status sort would be redundant.
|
|
*/
|
|
export const FINDINGS_FILTERED_SORT = composeSort(
|
|
FINDINGS_SEVERITY_HIGH_FIRST,
|
|
FINDINGS_RECENT_INSERT,
|
|
);
|
|
|
|
/**
|
|
* Resource-detail drawer "other findings" tab. Pairs with a server-side
|
|
* `filter[status]=FAIL`, so status is omitted. Uses `-updated_at` because
|
|
* `/findings/latest` exposes `updated_at`, not `inserted_at`.
|
|
*/
|
|
export const RESOURCE_DRAWER_OTHER_FINDINGS_SORT = composeSort(
|
|
FINDINGS_SEVERITY_HIGH_FIRST,
|
|
FINDINGS_RECENT_UPDATE,
|
|
);
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Presets — Family B
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Default for finding-groups list endpoints. FAIL groups first, then by
|
|
* severity, then by `new` deltas (deltas matter on group endpoints since
|
|
* `delta_order` is a real ordering column).
|
|
*/
|
|
export const FINDING_GROUPS_DEFAULT_SORT = composeSort(
|
|
FG_FAIL_FIRST,
|
|
FG_SEVERITY_HIGH_FIRST,
|
|
FG_DELTA_NEW_FIRST,
|
|
FG_RECENT_LAST_SEEN,
|
|
);
|
|
|
|
/**
|
|
* Default for the per-group resources sub-endpoint
|
|
* (`/finding-groups/{id}/resources`). Same shape as the groups list because
|
|
* `_RESOURCE_SORT_MAP` exposes the same computed columns.
|
|
*/
|
|
export const FINDING_GROUP_RESOURCES_DEFAULT_SORT = composeSort(
|
|
FG_FAIL_FIRST,
|
|
FG_SEVERITY_HIGH_FIRST,
|
|
FG_DELTA_NEW_FIRST,
|
|
FG_RECENT_LAST_SEEN,
|
|
);
|
|
|
|
/**
|
|
* Default for the `/findings` PAGE (which renders finding-groups, NOT plain
|
|
* findings) when the URL already constrains `filter[status__in]` and/or
|
|
* `filter[delta__in]`. Status and delta sort would be redundant.
|
|
*
|
|
* IMPORTANT: do NOT pass `inserted_at` here — `_FINDING_GROUP_SORT_MAP`
|
|
* does not expose it; valid recency keys are `last_seen_at`, `first_seen_at`,
|
|
* and `failing_since`.
|
|
*/
|
|
export const FINDING_GROUPS_FILTERED_SORT = composeSort(
|
|
FG_SEVERITY_HIGH_FIRST,
|
|
FG_RECENT_LAST_SEEN,
|
|
);
|