Files
vulncheck/frontend/types/index.ts
T
vulncheck d50c5144f4 feat(auth): idle timeout and maximum session age, session-only cookies
Sessions used to last as long as a 7-day refresh token kept being renewed,
and the auth cookies outlived a browser restart. Settings -> Security now
sets an idle timeout (default 15 min, 5 min to 3 h) and a maximum session
length (default 10 h, 1 to 12 h); both are clamped when read.

The refresh token lives exactly the idle timeout and is renewed on activity.
The access token lives half of it, at most 30 min. Every token carries
sat (sign-in time), copied on refresh: nothing outlives sat + max, and
/auth/refresh refuses past it. That holds for password, MFA, passkey, SAML
and OIDC sign-ins alike. Refresh tokens from before sat are refused, so
everyone signs in once after the upgrade.

Auth cookies are session cookies and go when the browser closes. In the
SPA, SessionGuard renews on load and on keyboard/mouse activity and takes
the page to /login when the idle timeout or maximum age passes, so an
abandoned screen does not stay readable. Activity is shared across tabs.
2026-11-04 08:55:48 +01:00

282 lines
10 KiB
TypeScript

export interface DashboardStats {
critical_count: number;
high_count: number;
medium_count: number;
low_count: number;
total_vulnerabilities: number;
open_vulnerabilities: number;
affected_assets: number;
total_assets: number;
scanned_assets: number;
severity_history: { day: string, count: number }[];
avg_cvss_score: number;
oldest_vulnerability_days: number;
}
export interface PriorityBreakdown {
total: number;
cvss: number;
exploit_bonus: number;
exploit_source: 'kev' | 'euvd' | 'kev_and_euvd' | 'epss' | 'wazuh' | 'ssvc' | 'maturity' | 'metasploit' | 'exploit_db' | 'poc_github' | 'none';
// Plan M — public-exploit catalog counts (already folded into
// exploit_bonus via max(); shown for transparency).
exploit_db_count?: number;
pocs_github_count?: number;
metasploit_module_count?: number;
exploit_status?: 'none' | 'poc' | 'active' | 'widespread'; // SSVC exploitation status
ssvc_addon?: number; // bonus from technical_impact + automatable
ssvc_technical_impact?: 'partial' | 'total' | null;
ssvc_automatable?: 'yes' | 'no' | null;
exploit_maturity?: string | null; // Unproven | PoC | Functional | High
asset_factor: number;
age_bonus: number;
kev_bonus: number;
euvd_bonus?: number;
catalog_count?: number;
cpr?: number | null;
vpr_score?: number | null; // Tenable VPR mirrored into breakdown
epss_score?: number | null;
epss_percentile?: number | null;
kev_listed: boolean;
kev_ransomware_use: boolean;
euvd_listed?: boolean;
euvd_critical?: boolean;
}
export interface VulnerabilityPackage {
package_name: string;
package_version?: string | null;
fixed_version?: string | null;
source?: string | null; // wazuh | nessus | manual
has_fix: boolean; // True iff fixed_version is real (not equal to installed)
}
export interface Vulnerability {
id: number;
cve_id: string;
severity: 'critical' | 'high' | 'medium' | 'low' | 'none';
cvss_score: number;
status: 'open' | 'patched' | 'pending_verification' | 'patch_failed' | 'accepted_risk' | 'false_positive' | 'deferred';
description: string;
package_name?: string;
package_vendor?: string | null; // vendor/publisher from Wazuh/Intune/Defender
package_version?: string;
fixed_version?: string | null; // when set + status='open' → patch available
packages?: VulnerabilityPackage[]; // per-package detail (CVE-2023-48795 hits PuTTY + WinSCP both)
has_fix_any?: boolean; // at least one package has a real fix (not equal to installed)
published_date: string;
last_modified_date?: string | null;
remediation?: string | null; // scanner-provided fix guidance (Nessus solution)
detected_at?: string;
asset_id: number;
asset_hostname?: string;
runs_on?: { id: number; hostname: string }[]; // Docker host(s) of a container-image finding
title?: string;
assigned_user_id?: number | null;
assigned_user_name?: string | null;
assigned_group_id?: number | null;
assigned_group_name?: string | null;
deferred_until?: string | null;
defer_reason?: string | null;
notification_suppressed?: boolean;
priority_score?: number;
priority_breakdown?: PriorityBreakdown;
exploit_available?: boolean;
exploit_maturity?: string; // Unproven, PoC, Functional, High (from Nessus)
exploitation_status?: 'none' | 'poc' | 'active' | 'widespread'; // SSVC (from Vulnrichment)
exploitation_source?: string; // nessus, vulrighment, nvd, manual
ssvc_technical_impact?: 'partial' | 'total' | null; // SSVC: attacker takeover scope
ssvc_automatable?: 'yes' | 'no' | null; // SSVC: mass-exploitation feasibility
// Multi-scanner source attribution (Nessus integration)
sources?: string[]; // ["wazuh"], ["nessus"], ["wazuh","nessus"]
cross_confirmed?: boolean; // sources.length >= 2
first_detected_by?: string | null;
nessus_plugin_id?: string | null;
nessus_vpr_score?: number | null; // Tenable's VPR (0-10)
is_pseudo_cve?: boolean; // NESSUS-PLUGIN-* (Compliance/Cipher) OR EOL-*
is_eol_finding?: boolean; // endoflife.date pseudo-CVE (cve_id starts with "EOL-")
// Plan M — public-exploit catalogs
exploit_db_count?: number;
exploit_db_ids?: string[] | null;
pocs_github_count?: number;
pocs_github_urls?: string[] | null;
metasploit_module_count?: number;
metasploit_modules?: string[] | null;
exploit_intel_updated_at?: string | null;
last_change?: { // latest audit entry for status tooltip
timestamp: string | null;
username: string;
old_status: string | null;
new_status: string | null;
reason: string | null;
source: string | null; // manual / manual_bulk / nessus_sync / wazuh_sync
} | null;
// Threat intel enrichment
epss_score?: number | null;
epss_percentile?: number | null;
kev_listed?: boolean;
kev_ransomware_use?: boolean;
kev_date_added?: string | null;
euvd_listed?: boolean;
euvd_critical?: boolean;
euvd_date_added?: string | null;
euvd_id?: string | null;
cpr_score?: number | null;
enrichment_sources?: string | null;
enrichment_updated_at?: string | null;
}
export interface Asset {
id: number;
hostname: string;
ip_address: string;
operating_system: string;
os_version?: string;
// VMware VMkernel/vpxd build number (e.g. "24784735") — shown in the OS column.
vmware_build?: string | null;
last_scan?: string;
wazuh_agent_id?: string | null;
nessus_host_uuid?: string | null;
intune_device_id?: string | null;
defender_machine_id?: string | null;
// Entra/AAD device id — survives an Intune deletion, so it is the handle
// for finding (and excluding) the same device in Defender TVM.
aad_device_id?: string | null;
vmware_uuid?: string | null;
vmware_serial?: string | null;
igel_unit_id?: string | null;
igel_serial?: string | null;
netdisco_device_ip?: string | null;
netdisco_serial?: string | null;
xen_host_uuid?: string | null;
intune_serial?: string | null;
last_seen_source?: string | null;
source?: 'wazuh' | 'nessus' | 'manual' | 'intune';
status: 'active' | 'inactive' | 'decommissioned';
policy_id?: number | null;
description?: string;
location?: string;
owner?: string;
assigned_user_id?: number | null;
assigned_user_name?: string | null;
groups?: string[]; // List of group names (M2M relationship)
policy_name?: string | null;
criticality?: string | null;
// Network-exposure risk dimension (Wazuh syscollector ports)
network_exposure_score?: number | null;
exposed_services?: { port: number; proto: string; service: string; risk: number; local_ip?: string }[] | null;
high_value_score?: number | null;
risk_dimensions?: { role: string; label: string; weight: number }[] | null;
exposure_updated_at?: string | null;
// Open findings on this asset (same number as the CSV's "Open Vulnerabilities").
vulnerability_count?: number;
// Dockhand: a Docker host's number of images, an image's Docker hosts.
container_image_count?: number;
runs_on?: { id: number; hostname: string }[];
}
export interface UserInfo {
id: number;
username: string;
email: string;
role: 'admin' | 'editor' | 'readonly';
passkey_suggested?: boolean; // show the "add a passkey" hint
// Limits SessionGuard enforces on screen; expires_at is epoch seconds.
session?: { idle_timeout_minutes: number; expires_at: number };
}
export interface Group {
id: number;
name: string;
description?: string;
created_at: string;
member_count: number;
members: { id: number; username: string }[];
}
export interface NotificationLogEntry {
id: number;
vulnerability_id?: number;
asset_id?: number;
user_id?: number;
notification_type: 'sla_breach' | 'assignment' | 'manual';
sent_at: string;
subject?: string;
recipient_email?: string;
status: 'sent' | 'failed' | 'suppressed';
error_message?: string;
cve_id?: string;
asset_hostname?: string;
username?: string;
}
export interface Scan {
id: number;
asset_id: number;
asset_hostname?: string;
scan_type: 'wazuh' | 'nessus' | 'full' | 'syscollector'; // legacy values kept for old history rows
status: 'pending' | 'running' | 'completed' | 'failed';
started_at: string;
completed_at?: string;
vulnerabilities_found: number;
}
export interface ScanRunSummary {
scan_ids: number[];
started_at: string;
completed_at?: string;
scan_type: 'wazuh' | 'nessus' | 'full' | 'syscollector'; // legacy values kept for old history rows
total_assets: number;
completed: number;
failed: number;
running: number;
total_vulns_found: number;
failed_assets: { asset_hostname: string; error_message: string }[];
}
export interface Recommendation {
cve_id: string;
asset_hostname: string;
priority: number;
justification: string;
remediation_hint: string;
}
export interface AIPriorityResponse {
recommendations: Recommendation[];
global_strategy: string;
error?: string;
}
// --- Sync run ledger (GET /api/v1/scans/sync-runs, /sync-health) ---
export interface SyncRun {
id: number;
source: string;
source_label: string;
trigger: 'manual' | 'scheduled' | string;
status: 'running' | 'completed' | 'failed' | string;
started_at: string;
finished_at: string | null;
error_message: string | null;
error_count: number;
stats: Record<string, any>;
alerted_at: string | null;
}
export interface SyncHealthSource {
source: string;
label: string;
state: 'ok' | 'warning' | 'failed' | 'stale' | 'running' | 'unconfigured';
configured: boolean;
last_run: SyncRun | null;
last_success_at: string | null;
error_message: string | null;
}
export interface SyncHealthResponse {
sources: SyncHealthSource[];
alert_enabled: boolean;
recipients: string[];
recipients_setting: string;
}