From 4fe530352d1b3f9f139db1caf833dfefb9e5ff5d Mon Sep 17 00:00:00 2001 From: Jaime Idolpx Date: Tue, 9 Jun 2026 04:52:45 -0400 Subject: [PATCH] feat(DeviceDetailOverlay): add URL validation and cache clearing for external URLs --- src/app/components/DeviceDetailOverlay.tsx | 25 +++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/app/components/DeviceDetailOverlay.tsx b/src/app/components/DeviceDetailOverlay.tsx index eac3d25..cc7d331 100644 --- a/src/app/components/DeviceDetailOverlay.tsx +++ b/src/app/components/DeviceDetailOverlay.tsx @@ -148,6 +148,17 @@ export default function DeviceDetailOverlay({ updateDeviceSetting([...path, 'url'], file); }; + const isOutsideBase = (url: string, baseUrl: string): boolean => { + if (!baseUrl || !url.startsWith('/')) return false; + const normalizedBase = baseUrl.endsWith('/') ? baseUrl : baseUrl + '/'; + return url !== baseUrl && !url.startsWith(normalizedBase); + }; + + const clearBaseAndCache = (dev: any) => { + if ('base_url' in dev) dev.base_url = ''; + if ('cache' in dev) dev.cache = ''; + }; + const handleFileSelect = async (selectedPath: string) => { const devicePath = getDevicePath(); if (selectedPath.toLowerCase().endsWith('.lst')) { @@ -168,7 +179,8 @@ export default function DeviceDetailOverlay({ const newConfig = JSON.parse(JSON.stringify(config)); let dev = newConfig; for (const k of devicePath) dev = dev[k]; - dev.url = files[0]; + if (isOutsideBase(files[0], dev.base_url || '')) clearBaseAndCache(dev); + dev.url = files[0]; dev.media_set = files; setConfig(newConfig); } catch (e: any) { @@ -178,6 +190,7 @@ export default function DeviceDetailOverlay({ const newConfig = JSON.parse(JSON.stringify(config)); let dev = newConfig; for (const k of devicePath) dev = dev[k]; + if (isOutsideBase(selectedPath, dev.base_url || '')) clearBaseAndCache(dev); dev.url = selectedPath; delete dev.media_set; setConfig(newConfig); @@ -342,8 +355,14 @@ export default function DeviceDetailOverlay({ type="text" value={deviceData.url} onChange={(e) => { - const path = getDevicePath(); - updateDeviceSetting([...path, 'url'], e.target.value); + const newUrl = e.target.value; + const devicePath = getDevicePath(); + const newConfig = JSON.parse(JSON.stringify(config)); + let dev = newConfig; + for (const k of devicePath) dev = dev[k]; + if (isOutsideBase(newUrl, dev.base_url || '')) clearBaseAndCache(dev); + dev.url = newUrl; + setConfig(newConfig); }} className="flex-1 px-3 py-2 border border-neutral-300 rounded-lg" />