diff --git a/src/context/DeviceContext.tsx b/src/context/DeviceContext.tsx index 9f0b6fa..3628fa2 100644 --- a/src/context/DeviceContext.tsx +++ b/src/context/DeviceContext.tsx @@ -1,6 +1,6 @@ -'use client'; - -import React, { createContext, useContext, useState, useEffect } from 'react'; +'use client'; + +import React, { createContext, useContext, useState, useEffect, useRef } from 'react'; import api from '@/lib/axios'; import type { AxiosError } from 'axios'; import { useAuth } from '@/context/AuthContext'; @@ -128,6 +128,20 @@ const toNonEmptyString = (value: unknown, fallback = ''): string => { return candidate && candidate.length > 0 ? candidate : fallback; }; +const sanitizeName = (value: string, hostname: string): string => { + const trimmed = value.trim(); + if (!trimmed) return ''; + if (trimmed.toLowerCase() === hostname.toLowerCase()) return ''; + if (/^[A-Z0-9_-]+$/.test(trimmed)) return ''; + return trimmed; +}; + +const sanitizeArchitecture = (value: string): string => { + const trimmed = value.trim(); + if (!trimmed || trimmed === '-1') return ''; + return trimmed; +}; + const parseSizeToGB = (value: unknown): number => { if (value === null || value === undefined) return 0; @@ -563,24 +577,26 @@ const normalizeDevice = (rawInput: unknown): DetailedDevice => { return { deviceId, hostname, - osName: toNonEmptyString( - resolveValue( - raw, - ['osName', 'os_name', 'operatingSystem', 'os'], - [ - 'osName', - 'os_name', - 'operatingSystem', - 'operating_system', - 'operatingSystemName', - 'operating_system_name', - 'osFriendlyName', - 'os_caption', - 'oscaption', - 'os', - ] - ) ?? '', - '' + osName: sanitizeName( + toNonEmptyString( + resolveValue( + raw, + ['osName', 'os_name', 'operatingSystem', 'os'], + [ + 'osName', + 'os_name', + 'operatingSystem', + 'operating_system', + 'operatingSystemName', + 'operating_system_name', + 'osFriendlyName', + 'os_caption', + 'oscaption', + ] + ) ?? '', + '' + ), + hostname ), osVersion: toNonEmptyString( resolveValue(raw, ['osVersion', 'os_version', 'osVersionString'], [ @@ -612,7 +628,8 @@ const normalizeDevice = (rawInput: unknown): DetailedDevice => { ]) ?? '', '' ), - osArchitecture: toNonEmptyString( + osArchitecture: sanitizeArchitecture( + toNonEmptyString( resolveValue(raw, ['osArchitecture', 'os_architecture', 'architecture'], [ 'osArchitecture', 'os_architecture', @@ -621,6 +638,7 @@ const normalizeDevice = (rawInput: unknown): DetailedDevice => { 'osarch', ]) ?? '', '' + ) ), processorName: toNonEmptyString( resolveValue(raw, ['processorName', 'processor_name', 'cpuName'], [ @@ -770,11 +788,12 @@ export const DeviceProvider = ({ const [detailedCveLookup, setDetailedCveLookup] = useState<{ [cveId: string]: DeviceVulnerability }>({}); - const [cachedSoftware, setCachedSoftware] = useState([]); // ⬅️ NEW - - const [loading, setLoading] = useState(!initialData); - - const { username, roles, loading: authLoading } = useAuth(); + const [cachedSoftware, setCachedSoftware] = useState([]); // ⬅️ NEW + + const [loading, setLoading] = useState(!initialData); + + const { username, roles, loading: authLoading } = useAuth(); + const rawDevicesRef = useRef([]); useEffect(() => { if (devices.length > 0 || initialData || authLoading || !username) return; @@ -799,8 +818,10 @@ export const DeviceProvider = ({ console.groupEnd(); // STEP 1: Set basic data (keep original UTC timestamps for calculations) - const normalizedDevices = Array.isArray(devicesRes.data?.devices) - ? (devicesRes.data.devices as unknown[]).map((device) => normalizeDevice(device)) + const rawDevices = Array.isArray(devicesRes.data?.devices) ? (devicesRes.data.devices as unknown[]) : []; + rawDevicesRef.current = rawDevices; + const normalizedDevices = rawDevices.length + ? rawDevices.map((device) => normalizeDevice(device)) : []; setDevices(normalizedDevices); @@ -866,13 +887,16 @@ const cveDetailsRes = await api.get('/vuln/cves/lookup', fetchDevicesVulnsAndSoftware(); }, [devices.length, initialData, username, authLoading, roles]); - useEffect(() => { - console.log("🧠 Devices updated:", devices); - }, [devices]); - - if (typeof window !== 'undefined') { - (window as Window & { __debug_devices?: DetailedDevice[] }).__debug_devices = devices; - } + useEffect(() => { + console.log('🧠 Devices updated:', devices); + if (typeof window !== 'undefined') { + (window as Window & { + __debug_devices?: DetailedDevice[]; + __debug_rawDevices?: unknown[]; + }).__debug_devices = devices; + (window as Window & { __debug_rawDevices?: unknown[] }).__debug_rawDevices = rawDevicesRef.current; + } + }, [devices]); return (