mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-12 14:34:16 +00:00
+23









Josema Camacho
César Arroba
Alan Buscaglia
Claude
Andoni Alonso
Rubén De la Torre Vico
HugoPBrito
Hugo Pereira Brito
Pepe Fagoaga
Copilot Autofix powered by AI
Chandrapal Badshah
Chandrapal Badshah
Adrián Peña
Pedro Martín
KonstGolfi
lydiavilchez
Prowler Bot
prowler-bot
StylusFrost
dependabot[bot]
alejandrobailo
Alejandro Bailo
Víctor Fernández Poyatos
bota4go
Daniel Barranquero
Daniel Barranquero
mchennai
Ryan Nolette
Ulissis Correa
Sergio Garcia
Lee Trout
Sergio Garcia
Alan-TheGentleman
032499c29a
Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: César Arroba <19954079+cesararroba@users.noreply.github.com> Co-authored-by: Alan Buscaglia <gentlemanprogramming@gmail.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com> Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com> Co-authored-by: HugoPBrito <hugopbrit@gmail.com> Co-authored-by: Hugo Pereira Brito <101209179+HugoPBrito@users.noreply.github.com> Co-authored-by: Pepe Fagoaga <pepe@prowler.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: Chandrapal Badshah <Chan9390@users.noreply.github.com> Co-authored-by: Chandrapal Badshah <12944530+Chan9390@users.noreply.github.com> Co-authored-by: Adrián Peña <adrianjpr@gmail.com> Co-authored-by: Pedro Martín <pedromarting3@gmail.com> Co-authored-by: KonstGolfi <73020281+KonstGolfi@users.noreply.github.com> Co-authored-by: lydiavilchez <114735608+lydiavilchez@users.noreply.github.com> Co-authored-by: Prowler Bot <bot@prowler.com> Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com> Co-authored-by: StylusFrost <43682773+StylusFrost@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: alejandrobailo <alejandrobailo94@gmail.com> Co-authored-by: Alejandro Bailo <59607668+alejandrobailo@users.noreply.github.com> Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com> Co-authored-by: bota4go <108249054+bota4go@users.noreply.github.com> Co-authored-by: Daniel Barranquero <74871504+danibarranqueroo@users.noreply.github.com> Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com> Co-authored-by: mchennai <50082780+mchennai@users.noreply.github.com> Co-authored-by: Ryan Nolette <sonofagl1tch@users.noreply.github.com> Co-authored-by: Ulissis Correa <123517149+ulissisc@users.noreply.github.com> Co-authored-by: Sergio Garcia <hello@mistercloudsec.com> Co-authored-by: Lee Trout <ltrout@watchpointlabs.com> Co-authored-by: Sergio Garcia <sergargar1@gmail.com> Co-authored-by: Alan-TheGentleman <alan@thegentleman.dev>
90 lines
2.7 KiB
TypeScript
90 lines
2.7 KiB
TypeScript
import { MetaDataProps } from "@/types";
|
|
import { AttackPathScan, AttackPathScansResponse } from "@/types/attack-paths";
|
|
|
|
/**
|
|
* Adapts raw scan API responses to enriched domain models
|
|
* - Transforms raw scan data with computed properties
|
|
* - Co-locates related data for better performance
|
|
* - Preserves pagination metadata for list operations
|
|
*
|
|
* Uses plugin architecture for extensibility:
|
|
* - Handles scan-specific response transformation
|
|
* - Can be composed with backend service plugins
|
|
* - Maintains separation of concerns between API layer and business logic
|
|
*/
|
|
|
|
/**
|
|
* Adapt attack path scans response with enriched data
|
|
*
|
|
* @param response - Raw API response from attack-paths-scans endpoint
|
|
* @returns Enriched scans data with metadata and computed properties
|
|
*/
|
|
export function adaptAttackPathScansResponse(
|
|
response: AttackPathScansResponse | undefined,
|
|
): {
|
|
data: AttackPathScan[];
|
|
metadata?: MetaDataProps;
|
|
} {
|
|
if (!response?.data) {
|
|
return { data: [] };
|
|
}
|
|
|
|
// Enrich scan data with computed properties
|
|
const enrichedData = response.data.map((scan) => ({
|
|
...scan,
|
|
attributes: {
|
|
...scan.attributes,
|
|
// Format duration for display
|
|
durationLabel: scan.attributes.duration
|
|
? formatDuration(scan.attributes.duration)
|
|
: null,
|
|
// Check if scan is recent (completed within last 24 hours)
|
|
isRecent: isRecentScan(scan.attributes.completed_at),
|
|
},
|
|
}));
|
|
|
|
// Transform links to MetaDataProps format if pagination exists
|
|
const metadata: MetaDataProps | undefined = response.links
|
|
? {
|
|
pagination: {
|
|
// Links-based pagination doesn't have traditional page numbers
|
|
// but we preserve the structure for consistency
|
|
page: 1,
|
|
pages: 1,
|
|
count: enrichedData.length,
|
|
itemsPerPage: [10, 25, 50, 100],
|
|
},
|
|
version: "1.0",
|
|
}
|
|
: undefined;
|
|
|
|
return { data: enrichedData, metadata };
|
|
}
|
|
|
|
/**
|
|
* Format duration in seconds to human-readable format
|
|
*
|
|
* @param seconds - Duration in seconds
|
|
* @returns Formatted duration string (e.g., "2m 30s")
|
|
*/
|
|
function formatDuration(seconds: number): string {
|
|
const minutes = Math.floor(seconds / 60);
|
|
const remainingSeconds = seconds % 60;
|
|
return `${minutes}m ${remainingSeconds}s`;
|
|
}
|
|
|
|
/**
|
|
* Check if a scan is recent (completed within last 24 hours)
|
|
*
|
|
* @param completedAt - Completion timestamp
|
|
* @returns true if scan completed within last 24 hours
|
|
*/
|
|
function isRecentScan(completedAt: string | null): boolean {
|
|
if (!completedAt) return false;
|
|
|
|
const completionTime = new Date(completedAt).getTime();
|
|
const oneDayAgo = Date.now() - 24 * 60 * 60 * 1000;
|
|
|
|
return completionTime > oneDayAgo;
|
|
}
|