Further update to devicesclient and devicescontext
All checks were successful
Deploy Frontend / deploy (push) Successful in 23s

This commit is contained in:
Bailey Taylor
2025-10-29 13:14:02 +08:00
parent 10d65a89b4
commit ae55ac7079

View File

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